2017-07-11 3 views
0

Je génère une paire de clés EC dans BouncyCastle C# et j'essaie d'exporter la clé privée dans un fichier PEM en utilisant le PemWriter. Le code pour le faire est la suivante:Exportation de clés privées C# BouncyCastle EC à l'aide de PemWriter

var ecKeyPairGenerator = new ECKeyPairGenerator(); 
CKeyGenerationParameters ecKeyGenParams = new ECKeyGenerationParameters(SecObjectIdentifiers.SecP384r1, new SecureRandom()); 
ecKeyPairGenerator.Init(ecKeyGenParams); 
AsymmetricCipherKeyPair pair = ecKeyPairGenerator.GenerateKeyPair(); 

string path = @"c:\tmp\test\myprivkey.pem"; 
TextWriter textWriter = new StreamWriter(path); 
PemWriter pemWriter = new PemWriter(textWriter); 
// passing pair results in the private key being written out 
pemWriter.WriteObject(pair); 
pemWriter.Writer.Flush(); 
pemWriter.Writer.Close(); 

Un exemple de sortie de l'extrait ci-dessus est:

-----BEGIN EC PRIVATE KEY----- 
MD4CAQEEMJvNXtTUd7A/fY/9/LSXM+Xb/6QS7GydeART/OieN3zh23Uuy0tgiS1D 
rohXMgiPvqAHBgUrgQQAIg== 
-----END EC PRIVATE KEY----- 

Cependant, lorsque vous faites la même chose en utilisant « OpenSSL » et la même courbe CE (secp384r1), le fichier PEM résultant est tout à fait différente, par exemple ,:

openssl ecparam -name secp384r1 -genkey -out mykey2.pem -noout 

-----BEGIN EC PRIVATE KEY----- 
MIGkAgEBBDBqCE9+AWL56cvR2/tRNdyaTIlJnfr6TbhCG+Q48w6yyKR+hE0jkeOV 
7yh1t8NwqT6gBwYFK4EEACKhZANiAAS2uLv7KG6RRBZBOecaxBz8FsMobnxgZkbQ 
8cKdL1DRym1lUDwgfX8AxOC6qkuD1k0UekpHcwiy1mSghy4640qBAKcR3mVghMVF 
77Nm8x6nwNijWZroeqhjrw268PPPuAw= 
-----END EC PRIVATE KEY----- 

Comme vous pouvez le voir, la longueur de clé est très différente, et le fichier P12 je crée avec l'ancien ne soit pas importé dans le cert de Windows st minerais. Je dois faire quelque chose de mal avec C# BouncyCastle mais ne peux pas voir quoi (en regardant le code source de PemWriter et d'autres classes connexes ne pointe pas vers des erreurs évidentes).

Toute aide serait grandement appréciée. Merci.

+0

Lors de l'examen de la clé privée généré BC- Le fichier PEM avec openssl, openssl signale correctement les champs "Clé privée", "ASN1 OID" et "NIST CURVE", les deux derniers ayant les mêmes valeurs que celles du fichier PEM généré par openssl. Pourtant, CertUtil ne parvient pas à "vider" le fichier P12 créé avec la clé privée PEM générée par BC tout en réussissant à le faire avec le P12 créé avec la clé privée générée par openssl PEM. – hyongsop

+0

Ils utilisent probablement des encodages de différents types asn.1. Essayez d'exécuter 'openssl asn1parse -i -dump -i key.pem' sur les deux clés pour vérifier cela. – mat

+0

@mat Oui, je faisais juste ça. Il semble que le fichier BC PEM manque la clé réelle ?? La sortie ans1parse du fichier PEM openssl a une structure supplémentaire manquante dans le fichier BC PEM. Cette structure ressemble à: ** ... 65: d = 1 hl = 2 l = 100 contre: cont [1] 67: d = 2 hl = 2 l = 98 prim: BIT STRING ... * * Cette structure se trouve à la fin du fichier PEM openssl et le reste du fichier précédant cette structure est identique à celui du fichier BC. Comment trouver les types asn.1 des fichiers PEM? – hyongsop

Répondre

0

Il se trouve que vous pouvez créer une instance de ECPrivateKeyStructure avec les clés publiques et privées et enregistrer la chaîne Base64 de l'objet fichier, par exemple ,:

... 
int orderBitLength = privKeyParam.Parameters.N.BitLength; 
X962Parameters x962 = new X962Parameters(privKeyParam.PublicKeyParamSet); 
ECPrivateKeyStructure privKeyStruct = 
        new ECPrivateKeyStructure(orderBitLength, privKeyParam.D, pubKeyInfo.PublicKeyData, x962); 

string header = @"-----BEGIN EC PRIVATE KEY-----"; 
string privKeyStr = Convert.ToBase64String(privKeyStruct.GetDerEncoded(), 
        Base64FormattingOptions.InsertLineBreaks); 
string tail = @"-----END EC PRIVATE KEY-----"; 

string path = @"c:\tmp\myprivkey.pem"; 
TextWriter textWriter = new StreamWriter(path); 
textWriter.WriteLine(header); 
textWriter.WriteLine(privKeyStr); 
textWriter.WriteLine(tail); 
textWriter.Flush(); 
textWriter.Close(); 
...