2011-02-23 12 views
14

Estoy usando RSA (Bouncy Castle API) en mi proyecto de C#. Me genera el par de claves con este método:Bouncy Castle, RSA: transformar claves en un formato de cadena

RsaKeyPairGenerator r = new RsaKeyPairGenerator(); 
r.Init(new KeyGenerationParameters(new SecureRandom(), 1024)); 
AsymmetricCipherKeyPair keys = r.GenerateKeyPair(); 

AsymmetricKeyParameter private_key = keys.Private; 
AsymmetricKeyParameter public_key = keys.Public; 

Ahora quiero guardarlas en un archivo txt pero el problema es que no puedo convertirlos a un formato de cadena. Leí en otra publicación que las claves deben ser serializadas usando:

PrivateKeyInfo k = PrivateKeyInfoFactory.CreatePrivateKeyInfo(private_key); 
byte[] serializedKey = k.ToAsn1Object().GetDerEncoded(); 

¿Es la manera correcta? En caso afirmativo, ¿qué debo hacer después de esto? ¿Simplemente convertirlos de byte [] a String?

Respuesta

7

Bueno, no sé sobre el lado específico de RSA, pero una vez que tienes una cadena binaria opaca (es decir, podría contener datos arbitrarios) la mejor opción para la conversión de texto es Convert.ToBase64String(byte[]) que puedes revertir con Convert.FromBase64String(string).

¿No uso Encoding.GetString(byte[]) y Encoding.GetBytes(string) para esto - los datos binarios no es texto en una codificación particular, y no deben ser tratados como tales. Estás casi obligado a perder datos si pruebas esto.

+0

gracias por su respuesta rápida. Hice lo que dijo y como resultado obtuve esto ** MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAJ7s/B4XNHmNa9LwZ91z ... ** Creo que debería ser un BigInteger, ¿no? porque en RSA usamos números (p, q ...) – Skeenor

+0

El nombre del método (GetDerEncoded) sugiere que los datos devueltos contienen todos los parámetros clave RSA (p, q, ...) en formato codificado DER. –

+0

@Rami: ¿Su objetivo es obtener algo que pueda "rehidratar" de nuevo a un PrivateKeyInfo? Si es así, no necesita saber los enteros, etc. ... solo quiere asegurarse de que pueda serializar a una matriz de bytes (y luego a una cadena) y viceversa. –

18

También es posible usar PemWriter almacenarlos en formato PEM:

TextWriter textWriter = new StringWriter(); 
PemWriter pemWriter = new PemWriter(textWriter); 
pemWriter.WriteObject(keys.Private); 
pemWriter.Writer.Flush(); 

string privateKey = textWriter.ToString(); 

Ahora PrivateKey contiene algo como esto:

-----BEGIN RSA PRIVATE KEY----- 
MIICXQIBAAKBgQDFhB3xI1AzSMsKvt7rZ7gp2o/vd49zON89iL1ENvKkph7oFXa2 
ew/hjzbAV33lHnFFlA/vA5SDCbggRyU1/SmjfuPJFEzFbgcPLuO1Sw6z+bWXiIFp 
QNCOTIw11c0fbwk+kB2y4E1OkLv5f9atlNlekb4wBn8bMbFYtu6LGWjkFQIDAQAB 
AoGANPoMteLM3hSGMSmkzOsS4Fb5CDe/SB5W8kA805ERX8wWuhUXtDYpukwZWVme 
MNgLdagS5f7F1KfEtROgDW0Lv4/T/FWAbpgh8O2CPKYDY4ZXl8tmRH9dtYn/824l 
veLxdgNjHwo5OMvuTSDMjC3tbg2UA3kmV4VAm5QotlRinUECQQDo4zvI5e81zWnS 
kNrUARX80t432MOZyr0RvAaVJfBNQpJl0H0xp5LKP74hvPVO9WdJvJ0M4Z4QrmGO 
bm2Hsfz5AkEA2R469YXxgPLDg/LvUQqfrl8Ji9+rip7eQP7iS/dt66NMS31/HymT 
+HscEZ3qGlnQuyyyRR2rGQdhdjU42HNy/QJBAKbPTF1DxSmGbovyUauU84jaCW17 
B++6dd6kDRr7x7mvO2lOAr50RwIy0h8cV6EsycTZIqy9VhigryP0GOQfKxECQA8T 
uVZpab7hnNAh45qGGVabhOcwrhHfPGHZEU/jK7/sRBUN7vD0CzF7IxTaGXKhAAyv 
auW/zKzdRVhXE858HeUCQQCGaaAg8GwM0qIS0nHRTLldu4hIGjKn7Sk0Z46Plfwr 
oqPCtuP4ehX85EIhqCcoFnG6Ttr6AxSgNMZvErVxDBiD 
-----END RSA PRIVATE KEY----- 
+0

Esta respuesta es correcta, pero simplemente cambie la última línea, en lugar de 'cadena privateKey = pemWriter.ToString();' try 'string privateKey = textWriter.ToString();' – skw

1

Si convierte el certificado BouncyCastle a un certificado .NET . La función para hacer esto está en bouncycastle lib (creo que está en una clase llamada DotNetUtilities). El RSACryptoServiceProvider tiene una función:

ToXmlString(bool includePrivateKey). 

que le da una representación x de un certificado con si desea que la clave privada que contiene todos los componentes de base 64 serializado por separado, exponente, el módulo, y d (exponente privado).

Cuestiones relacionadas