2014-03-31 5 views
14

Wie kann ich die öffentlichen/private Schlüssel von einer ECC-basierten X509Certificate2 's in CngKey' s für die Verwendung mit ECDsaCng und ECDiffieHellmanCng bekommen?Importieren von ECC-basiertem Zertifikat aus dem Windows Certificate Store in CngKey

Ich verwende derzeit RSA 2048 Bit-Schlüsselpaare zum Signieren/Verschlüsseln von Daten. Ich mache das, indem ich die Zertifikate aus der X509Store, wo sie sicher mit privaten Schlüsseln als nicht exportierbar markiert sind ziehen. Ich möchte die aktuelle Implementierung in ECDSA und ECDH umwandeln, so dass ich kleinere Schlüsselgrößen für gleichwertige Sicherheit verwenden kann.

Ich habe erfolgreich generiert ECC Zert OpenSSL:

  1. openssl ecparam -out private.pem -name prime256v1 -genkey
  2. openssl req -new -key private.pem -x509 -nodes -days 365 -out public.cer
  3. openssl pkcs12 -export -in public.cer -inkey private.pem -out export.pfx

Ich habe erfolgreich die oben erzeugten certs in die cert Speicher installiert. Ich kann sie per Fingerabdruck abrufen, aber die Crypto-Provider für die privaten und öffentlichen Schlüssel werfen Ausnahmen "Algorithmus nicht unterstützt". Stattdessen verstehe ich, dass ich ECDsaCng und ECDiffieHellmanCng zum Signieren/Verschlüsseln verwenden soll. Aber diese handeln in CngKey 's.

Bouncy Castle ist keine Option, da die privaten Schlüssel exportierbar sind.

CLR Security kehren mir ein CngKey Paar über GetCngPrivateKey aber es kann nicht mit ECDSA verwendet werden, da der Schlüssel zurückgegeben von CLRSecurity ein ECDH Schlüssel. Außerdem gibt CLR Security mir keine Möglichkeit, nur den öffentlichen Schlüssel von einer X509Certificate2 zur Signaturverifizierung zu bekommen (wo ich nicht einmal den privaten Schlüssel des Unterzeichners habe oder brauche).

Irgendwelche Ideen? Ich bin am Ende meiner Weisheit ... Jede Hilfe wäre viel geschätzt.

Antwort

6

Sie müssen die CngKey aus dem öffentlichen Schlüssel des Zertifikats erstellen:

certificate.PublicKey.EncodedKeyValue.RawData

Die CngKey 8 zusätzliche Bytes enthält, werden die ersten 4 Bytes verwendet für den Namen der verwendeten Kurve (ECS1, ECS3 oder ECS5) sind die letzten 4 die Länge des Schlüssels inkl. Polsterung (32, 48 oder 66).

Das erste Byte des öffentlichen Schlüssels aus dem Zertifikat wird entfernt (wie es immer 0x04 für ECDSA öffentlichen Schlüssel ist).

So zum Beispiel für ECDSA mit P-256-Kurve und SHA-256 Hash-Algorithmus, erhalten Sie einen öffentlichen Schlüssel der Länge 65 Bytes. Verwerfe das erste Byte und lasse 64 Bytes, dann 4 Bytes für die Kurve und 4 Bytes für die Schlüssellänge, d. H. (Encoding.ASCII):

69 (E)

67 (C)

83 (S)

49 (1)

32 (Schlüssellänge)

Jetzt haben Sie die öffentlichen Schlüssel (72 Byte), um die CngKey erstellen aus:

var cngKey = CngKey.Import ([das Byte-Array], CngKeyBlobFormat.EccPublicBlob) ;

var ecdsaCng = neuer ECDsaCng (cngKey);

Und Sie können die Signatur überprüfen:

Rückkehr ecdsaCng.VerifyData (encodedBytes, Unterschrift);

+1

Aber ist hier nicht das Problem, dass "certificate.PublicKey" wirft, wenn der Schlüssel nicht auf RSA/DSA basiert? – EricLaw

Verwandte Themen