Fichier de signature ECDSA avec la clé du magasin C#.Net GNC

j'essaie de signer un fichier avec ECDSA en utilisant L'API CNG et un certificat du Microsoft Certificate Store. J'ai lu beaucoup de documentation et j'ai presque fini, mais j'ai du mal à importer la clé privée du certificat. J'ai fait la même chose avec RSA, mais il semble que ce soit fait très différemment. Voici le code que j'ai pour l'instant:

    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();
    }

Et j'obtiens le message d'erreur

Système.NotSupportedException: la clé de certificat l'algorithme n'est pas pris en charge.

mon certificat est ECDSA_P256 sha384ecsa avec les extensions suivantes:

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)

il semblerait que le certificat soit le problème mais je ne suis pas sûr que ce soit le code ou pas.


Voici mon certificat avec la clé publique:

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
19
demandé sur Kjartan 2012-05-08 02:59:01

3 réponses

j'ai combattu ECDsa et CngKey avec des certificats X509 pendant un bon moment et avait les mêmes problèmes. Nous avons fini par créer nos propres CngKeys avec ECDsa_P256 SHA256, mais je crois que j'ai appris quelque chose en creusant dans CryptoApi:

lorsque vous avez un certificat qui est marqué "authentification du serveur (1.3.6.1.5.5.7.3.1)" (utiliser comme certificat SSL), votre certificat contiendra L'algorithme d'échange de clés ECDH. Et d'une manière ou d'une autre, cela "a priorité" sur L'ECDsa algorithme de groupe. Ainsi, vous obtenez le redouté "l'algorithme de clé de certificat n'est pas supporté".

J'ai passé plus d'une heure avec Symantec à regarder par-dessus mon épaule et ils n'ont pas pu résoudre le puzzle, donc ils ont abandonné avec un "Désolé, nous ne supportons pas l'utilisation de certs SSL pour quoi que ce soit D'autre que SSL".

Vous pouvez obtenir votre CngKey privé du cert avec CLRSecurity à partir de Codeplex (http://clrsecurity.codeplex.com/). Cela donne à votre x509Certificate2 une extension qui permet pour ce code:

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

Inspectez " k " et voyez que votre groupe d'algorithmes est probablement quelque chose d'autre que prévu. Le mien était L'ECDH...

la Solution que je suis en train d'essayer maintenant est de mettre en place un nouveau serveur d'autorité de certification de la forcer à faire exactement ce que je veux. Fondamentalement, ce serait un certificat X509 qui N'est utilisé que pour la signature de code...

"Utilisation de la Clé X509v3: critique de Signature Numérique" peut-être la SEULE utilisation autorisée...

Espérons que cela aide quelqu'un d'autre : -)

6
répondu Henrik N. 2017-07-10 06:38:58

.NET 4.6.1 a résolu les principaux besoins de ce problème. Le nouveau code doit être

...
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 a également corrigé la question où certaines clés cert reviennent comme ECDH et échouent. (Bien, cela n'a pas résolu le problème de certaines clés privées étant considérées comme ECDH-qui n'avait rien à voir avec le serveur Auth EKU, mais était une bonne supposition-mais considère que ces clés sont valides maintenant).

4
répondu bartonjs 2016-08-19 14:53:25

si vous utilisez Windows Vista ou Windows 2008, le CngKeyBlobFormat.EccPrivateBlob n'est pas supporté. Quel système D'exploitation utilisez-vous? CngKey.Import lance CryptographicException seulement sur certaines machines

2
répondu Anssssss 2012-08-22 17:03:55