2012-05-07 10 views
19

CNC APIとMicrosoft証明書ストアの証明書を使用してECDSAでファイルに署名しようとしています。私は多くのドキュメントを読んできましたが、近くでは終わりましたが、私は証明書から秘密鍵をインポートすることにつきました。私はRSAでこれと同じことをやったことがありますが、それは非常に異なっているようです。ここで私がこれまで持っているコードです:ストアのキーを持つECDSA署名ファイルC#.Net CNG

static void signFile() 
    { 
     X509Certificate2 myCert = 
      selectCert(StoreName.My, 
         StoreLocation.CurrentUser, 
         "Select a Certificate", 
         "Please select a certificate from the list below:"); 

     Console.Write("Path for file to sign: "); 
     string path = Console.ReadLine(); 
     TextReader file = null; 
     try 
     { 
      file = new StreamReader(path); 
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e.Message); 
      Console.Write("\nPress any key to return to the main menu: "); 
      Console.ReadKey(); 
     } 
     UnicodeEncoding encoding = new UnicodeEncoding(); 
     byte[] data = encoding.GetBytes(file.ReadToEnd()); 
     ECDsaCng dsa = new ECDsaCng(
      CngKey.Import(StringToByteArray(myCert.PrivateKey.ToString()), 
          CngKeyBlobFormat.EccPrivateBlob, 
          CngProvider.MicrosoftSoftwareKeyStorageProvider)); 

     dsa.HashAlgorithm = CngAlgorithm.Sha384; 
     byte[] sig = dsa.SignData(data); 
     TextWriter signatureFile = new StreamWriter("signature.txt"); 
     signatureFile.WriteLine("-----BEGIN SHA384 SIGNATURE-----" + 
           ByteArrayToString(sig) + 
           "-----END SHA384 SIGNATURE-----"); 
     signatureFile.Close(); 
    } 

そして、私はエラーに

System.NotSupportedExceptionを取得:証明書のキーアルゴリズムがサポートされていません。

私の証明書には、以下の拡張子を持つECDSA_P256 sha384ECDSAです:証明書が問題だったかのように

Digital Signature, Non-repudiation, independent signing revocation list (CRL), CRL Signing (CRL) (c2) 
Server Authentication (1.3.6.1.5.5.7.3.1) 
Client Authentication (1.3.6.1.5.5.7.3.2) 
Code Signing (1.3.6.1.5.5.7.3.3) 
Unknown Key Usage (1.3.6.1.4.1.311.2.1.22) 
Unknown Key Usage (1.3.6.1.4.1.311.2.1.21) 
IKE-intermediary IP-security (1.3.6.1.5.5.8.2.2) 

は、それが表示されるだろうが、それはコードであるか、できなかった場合、私はよく分かりません。


はここで公開鍵と私の証明書です:あなたは、Windows VistaまたはWindows 2008を実行している場合

Certificate: 
Data: 
    Version: 3 (0x2) 
    Serial Number: 2 (0x2) 
Signature Algorithm: ecdsa-with-SHA384 
    Issuer: C=##, O=#######, OU=#####, OU=#####, CN=########### 
    Validity 
     Not Before: Apr 27 16:35:51 2012 GMT 
     Not After : Apr 26 16:35:51 2017 GMT 
    Subject: C=##, O=###########, OU=#####, CN=############# 
    Subject Public Key Info: 
     Public Key Algorithm: id-ecPublicKey 
      Public-Key: (256 bit) 
      pub: 
       04:fc:d5:ce:ad:1f:0c:19:b9:3d:2b:bd:7d:f0:8c: 
       44:46:db:e3:42:14:b1:1a:9f:7c:ab:e1:be:ad:a5: 
       0c:03:2d:0f:ff:3f:10:d4:69:eb:4c:82:a1:2a:61: 
       56:45:03:04:a6:49:f7:16:6e:dd:60:22:c6:20:c5: 
       4d:44:49:21:41 
      ASN1 OID: prime256v1 
    X509v3 extensions: 
     X509v3 Key Usage: critical 
      Digital Signature, Non Repudiation, CRL Sign 
     X509v3 Extended Key Usage: critical 
      TLS Web Server Authentication, TLS Web Client Authentication, Co 
de Signing, Microsoft Commercial Code Signing, Microsoft Individual Code Signing 
, 1.3.6.1.5.5.8.2.2 
     X509v3 Authority Key Identifier: 
      DirName:/C=##/O=#######/OU=#####/OU=#####/CN=###### 
      serial:01 
     X509v3 Subject Key Identifier: 
      B7:A8:F9:55:9A:43:9E:BE:1C:4B:62:52:91:C2:F1:39:72:E1:CE:1B 
     X509v3 Basic Constraints: critical 
      CA:FALSE 
Signature Algorithm: ecdsa-with-SHA384 
    30:81:88:02:42:01:75:55:f3:64:f9:aa:2a:66:55:b1:ca:dc: 
    86:ac:1f:7d:2a:ec:10:87:db:74:88:0e:77:e3:18:82:15:a7: 
    32:91:1a:2d:ea:07:2e:78:8d:dc:8a:18:3c:2b:5a:9b:6a:0f: 
    97:f6:f8:8d:c5:fc:0e:9f:20:e9:b0:16:90:1a:c4:58:ac:02: 
    42:01:dc:b3:88:ae:44:54:c4:e0:b7:c2:37:88:0b:19:6b:96: 
    99:f7:21:12:45:12:21:e5:ab:83:39:a6:47:3a:08:87:b0:fa: 
    0e:31:1b:97:83:8d:65:30:a1:43:c1:82:27:77:6e:93:89:1b: 
    bd:57:b1:7a:54:9e:cc:e1:44:cc:74:16:c5 
+0

マイクロソフトでは、楕円曲線暗号(ECC)のサポートがかなり制限されています。これは、NIST規格の素数曲線P-256、P-384、およびP-521上でのみ「楕円曲線DSA(ECDSA)」を提供します。それらは「名前付き」曲線でなければなりません。どのECドメインパラメータが証明書に含まれているか知っていますか?あるいは、証明書の16進数、base64、またはASN.1のテキストを貼り付けて見つけることができます。 –

+0

あなたは質問を編集して、答えを返す代わりに詳細情報を提供することができます。質問を再度読むと、証明書自体に秘密鍵が含まれていません。一般に、鍵ペアを作成し、公開鍵を含む証明書要求を作成し、秘密鍵で署名します。次に、CAはそれから証明書をベイクし、それを送り返す。その証明書には公開鍵のみが含まれています。だからあなたはプライベートキーをインポートしようとすると、どのような形式ですか? PKCS#12?それは '.pkf'か' .p12'のファイル拡張子です。 –

+0

ああ、どこが間違っているのか分かりますが、私の眼鏡をかけるべきです。 ToStringは秘密鍵をエンコードしません。秘密鍵に関する情報を表示するだけです。プライベートキーをエンコード/再エンコードする代わりに、PrivateKeyプロパティが実際に拡張する 'DSACryptoServiceProvider'を使用することができます。 –

答えて

2

、CngKeyBlobFormat.EccPrivateBlobはサポートされていません。あなたはどのOSを使用していますか? CngKey.Import throws CryptographicException only on some machines

+1

私はWindows 7を使っていましたが、今は "8"にアップグレードしました。 –

+0

私の答えは無視できます。その問題はWindows 7では起こりませんし、Windows 8でも起こりません。 – Anssssss

5

私はECDsaとCngKeyとX509証明書を使っていましたが、まったく同じ問題がありました。私たちはECDsa_P256 SHA256で独自のCngKeysを作成しましたが、私はCryptoApiを掘り下げて学んだと思います:

"Server Authentication(1.3.6.1.5.5.7.3.1 ) "(SSL証明書として使用)、証明書には鍵交換アルゴリズムECDHが含まれます。そして、どういうわけか、これはECDsaアルゴリズムグループよりも優先されます。したがって、あなたは恐ろしい "証明書キーアルゴリズムはサポートされていません"を得る。

シマンテックは私の肩を見渡してパズルを解決できなかったので、「SSL以外のものでSSL証明書の使用はサポートしていません」と諦めました。

個人用CngKeyは、Codeplex(http://clrsecurity.codeplex.com/)のCLRSecurityで証明書から取得できます。これはあなたのx509Certificate2にこのコードを許容する拡張機能を提供します:

X509Certificate cer = <getyourcertcode>; 
CngKey k = cer.GetCngPrivateKey(); 

「K」を点検し、あなたのアルゴリズムグループは、おそらく予想よりも何か他のものであることがわかります。私がECDHでした...

解決策私は今、私が望むことを実行するために強制的に新しいCAサーバを設定しようとしています。これは他の誰かを助け

希望...許可ONLYの使用する必要があります:基本的にそれは...

「重要なデジタル署名書X509v3キー使用法」ONLYコード署名に使用されるX509の証明書になりますそこに:-)

+0

公開鍵だけでCngKeyを作成するにはどうしたらいいですか?そのCLRSecurityライブラリは 'GetCngPublicKey()'拡張を提供していないようです。証明書ストアのX509Certificateで署名者の公開鍵だけでECDsa署名を検証するにはどうすればよいですか? –

+0

ここで私の答えを見て:http://stackoverflow.com/questions/10264770/creating-an-ecc-private-public-key-with-native-c-sharp/22637599#22637599。次のように確認してください:(ECDsaCng ecsdKey = new ECDsaCng(CngKey.Import(key、CngKeyBlobFormat.EccPublicBlob))) { if(ecsdKey.VerifyData(data、signature)) Console.WriteLine( "Data is good"); else Console.WriteLine( "データが不良です"); } –

+0

あなたの答えは、証明書ストアのX509証明書と何も関係していないようですか? –

2

.NET 4.6.1はこの問題の中核的なニーズを解決しました。新しいコードは

... 
byte[] sig; 
using (ECDsa ecdsa = cert.GetECDsaPrivateKey()) 
{ 
    if (ecdsa == null) throw new Exception("Not an ECDSA cert, or has no private key"); 

    sig = ecdsa.SignData(data, HashAlgorithmName.SHA384); 
} 

.NET 4.6.1はまた、いくつかの証明書キーがECDHとして戻ってくるので、失敗する問題を修正されるだろう。 (まあ、それはいくつかの秘密鍵がECDHとみなされている問題を解決しませんでした。これはServer Auth EKUとは関係ありませんでしたが、良い推測でしたが、これらの鍵は今有効であると考えています)。

関連する問題