2016-08-17 12 views
0

XMLメッセージにデジタル署名する際に問題があります。要件によって、ECDSA証明書を特定の曲線で使用するよう指示されます。 SignatureDescription,AsymmetricSignatureFormatterおよびAsymmetricSignatureDeformatterのカスタム実装を作成せずにSignedXml.ComputeSignature(...)メソッドによって提供されるRSAおよびDSA機能が機能しないことを意味します。キーが存在しません - 自己署名ECDSA証明書を使用

多くのコードを投稿していないと言われていますが、私は証明書を取得し、その公開鍵を使用してデータをECDsaCngクラスを使用して署名する必要がある単純な関数を作成しました。 。

私のカスタム実装でも、 "System.Security.Cryptography.CryptographicException: Key does not exist."という例外が発生します。ただし、インポートする代わりにCngKeyを作成すればうまく動作します。例外がスローされますなぜ私はこの例外がncrypt.dll

であるinternal static extern ErrorCode NCryptSignHash(...)上のメソッドを呼び出しているコードから放り出されている見ることができるものから、だから私の質問は、「System.Security.Cryptography.CryptographicException: Key does not exist.」と、それを解決する方法について説明します。

[TestMethod] 
public void CreateSignatureTest() 
{ 
    var request = "Some xml goes here..."; 

    var store = new X509Store(StoreLocation.LocalMachine); 
    store.Open(OpenFlags.ReadOnly); 
    var certificates = store.Certificates; 

    var applicableCertificate = certificates.Cast<X509Certificate2>() 
    .FirstOrDefault(certificate => certificate.Subject.Contains("ECDSA_CERT_NAME")); 

    var encryptingKey = (ECDsaCng)applicableCertificate.GetECDsaPublicKey(); 

    var exported = encryptingKey.Key.Export(CngKeyBlobFormat.EccPublicBlob); 
    var creationParameters = new CngKeyCreationParameters 
    { 
    ExportPolicy = CngExportPolicies.AllowPlaintextExport 
    }; 

    using (CngKey objCngKey = CngKey.Import(exported, CngKeyBlobFormat.EccPublicBlob)) // This will throw a Key Does Not Exist Exception 
    //using (CngKey objCngKey = CngKey.Create(CngAlgorithm.ECDsaP256, null, creationParameters)) // This works... 
    { 
    //'Convert String to be signed to a byte array 
    var data = Encoding.Default.GetBytes(request); 

    //'Create a ECDsaCng Object 
    var ecdsa = new ECDsaCng(objCngKey); 

    //'Sign the string 
    var bSignature = ecdsa.SignData(data); 

    //'Convert Signature to Base64 string for better reading 
    var sSignature = Convert.ToBase64String(bSignature); 
    } 
} 

答えて

2

公開鍵を取得しました。それを新しいコンテナにインポートし、Signと呼んだ。署名には秘密鍵が必要であるため、秘密鍵フィールドが存在しないという例外が投げられました。

なぜオブジェクトを複製するのですか? cert.GetECDsaPrivateKey()に電話して、そのオブジェクトを使用してください。

+0

私はこれを試しました var encryptingKey =(ECDsaCng)applicableCertificate.GetECDsaPrivateKey(); var exported =((ECDsaCng)encryptingKey).Key.Export(CngKeyBlobFormat.EccPrivateBlob);今すぐ別の例外を取得します。「要求された操作はサポートされていません。私は公開して暗号化し、受信者は秘密鍵に対して検証するという印象を受けましたか? – Geek

+1

これは暗号化の仕組みです。署名は反対です。署名者は秘密鍵(彼らが所有している)を使用し、検証者は公開鍵を使用します。しかし、私はまだあなたがなぜオブジェクトをクローンしているのか分かりません(スマートカードではうまくいかないでしょう)。 '' Sign.GetECDsaPrivateKey()。SignData(...) '(文を使うのは良いですが) – bartonjs

+0

最後のコメントは優れたポインタだったので、私はクローンを取り出しました。今私の唯一の問題は、これをカスタムSignatureDescription、AsymmetricSignatureFormatter、およびAsymmetricSignatureDeformatterの実装に適用して、Signature XML Nodeを作成する方法です。 – Geek

関連する問題