-->

从商店C#.NET CNG密钥ECDSA签署文件(ECDSA signing file with k

2019-07-29 07:23发布

我试图签订使用CNG API,并从Microsoft证书存储证书ECDSA的文件。 我已经通过大量的文档资料和阅读并接近完成,但我先挂了关于导入证书的私钥。 我已经做了RSA这个同样的事情,但它似乎是非常不同的做法。 这里是我到目前为止的代码:

    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)

这样看来好像证书的问题,但我不知道这是否可能是代码或不。


下面是我用公钥证书:

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

Answer 1:

我一直在争夺ECDSA和CngKey与X509证书的looong时间,有完全相同的问题。 我们结束了与ECDsa_P256 SHA256创建我们自己的CngKeys,但我相信,我学到了一些东西到CryptoAPI的挖掘:

当你有一个标有“服务器身份验证(1.3.6.1.5.5.7.3.1)”(如SSL证书使用)的证书,证书将包含密钥交换算法ECDH。 不知何故这个“优先”在ECDSA算法组。 因此,你得到“不支持的证书密钥算法”可怕的。

我花了一个多小时,赛门铁克找过我的肩膀,他们不可能解决这一难题,所以他们放弃了一个“对不起,我们不支持使用SSL证书的任何东西,但SSL”。

您可以从证书从Codeplex上(CLRSecurity让您的私人CngKey http://clrsecurity.codeplex.com/ )。 这使你的x509Certificate2的扩展,允许这样的代码:

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

检查“K”,看看你的算法组可能是别的比预期的东西。 我的是ECDH ...

解决方案现在我想是要建立一个新的CA服务器强迫它做的正是我想要的。 基本上,那将是一个X509证书是仅用于代码签名...

“采用X509v3密钥用法:关键数字签名”可能是唯一的允许使用...

希望这可以帮助别人那里:-)



Answer 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问题 - 这无关与服务器验证EKU,但他是一个很好的猜测 - 但认为这些键是有效的现在)。



Answer 3:

如果您运行的是Windows Vista或Windows 2008,不支持CngKeyBlobFormat.EccPrivateBlob。 什么操作系统您使用的? CngKey.Import引发CryptographicException仅适用于某些机器



文章来源: ECDSA signing file with key from store C#.Net CNG