Saltar al contenido

Cómo leer un PEM RSA privado key desde .NET

Esta crónica ha sido evaluado por nuestros expertos así garantizamos la veracidad de nuestra esta crónica.

Solución:

Lo resolví, gracias. En caso de que alguien esté interesado, Bouncycastle hizo el truco, solo me tomó un tiempo debido a la falta de conocimiento y documentación de mi parte. Este es el código:

var bytesToDecrypt = Convert.FromBase64String("la0Cz.....D43g=="); // string to decrypt, base64 encoded

AsymmetricCipherKeyPair keyPair; 

using (var reader = File.OpenText(@"c:myprivatekey.pem")) // file containing RSA PKCS1 private key
    keyPair = (AsymmetricCipherKeyPair) new PemReader(reader).ReadObject(); 

var decryptEngine = new Pkcs1Encoding(new RsaEngine());
decryptEngine.Init(false, keyPair.Private); 

var decrypted = Encoding.UTF8.GetString(decryptEngine.ProcessBlock(bytesToDecrypt, 0, bytesToDecrypt.Length)); 

Con respecto a importar fácilmente el RSA privado key, sin utilizar un código de terceros como BouncyCastle, creo que la respuesta es “No, no con un PEM de los key solo.”

Sin embargo, como Simone aludió anteriormente, simplemente puede combinar el PEM del privado key (*.key) y el archivo de certificado que usa ese key (* .crt) en un archivo * .pfx que luego se puede importar fácilmente.

Para generar el archivo PFX desde la línea de comando:

openssl pkcs12 -in a.crt -inkey a.key -export -out a.pfx

Luego use normalmente con la clase de certificado .NET como:

using System.Security.Cryptography.X509Certificates;

X509Certificate2 combinedCertificate = new X509Certificate2(@"C:pathtofile.pfx");

Ahora puede seguir el ejemplo de MSDN para cifrar y descifrar a través de RSACryptoServiceProvider:

Dejé fuera que para descifrar necesitaría importar usando la contraseña PFX y la bandera Exportable. (ver: BouncyCastle RSAPrivateKey a .NET RSAPrivateKey)

X509KeyStorageFlags flags = X509KeyStorageFlags.Exportable;
X509Certificate2 cert = new X509Certificate2("my.pfx", "somepass", flags);

RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey;
RSAParameters rsaParam = rsa.ExportParameters(true); 

Puede echar un vistazo a la fuente de JavaScience para OpenSSLKey

Hay un código que hace exactamente lo que quieres hacer.

De hecho, tienen una gran cantidad de código fuente criptográfico disponible aquí.


Fragmento de código fuente:

//------- Parses binary ans.1 RSA private key; returns RSACryptoServiceProvider  ---
public static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)

        byte[] MODULUS, E, D, P, Q, DP, DQ, IQ ;

        // ---------  Set up stream to decode the asn.1 encoded RSA private key  ------
        MemoryStream  mem = new MemoryStream(privkey) ;
        BinaryReader binr = new BinaryReader(mem) ;    //wrap Memory Stream with BinaryReader for easy reading
        byte bt = 0;
        ushort twobytes = 0;
        int elems = 0;
        try 
                twobytes = binr.ReadUInt16();
                if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)
                        binr.ReadByte();        //advance 1 byte
                else if (twobytes == 0x8230)
                        binr.ReadInt16();       //advance 2 bytes
                else
                        return null;

                twobytes = binr.ReadUInt16();
                if (twobytes != 0x0102) //version number
                        return null;
                bt = binr.ReadByte();
                if (bt !=0x00)
                        return null;


                //------  all private key components are Integer sequences ----
                elems = GetIntegerSize(binr);
                MODULUS = binr.ReadBytes(elems);

                elems = GetIntegerSize(binr);
                E = binr.ReadBytes(elems) ;

                elems = GetIntegerSize(binr);
                D = binr.ReadBytes(elems) ;

                elems = GetIntegerSize(binr);
                P = binr.ReadBytes(elems) ;

                elems = GetIntegerSize(binr);
                Q = binr.ReadBytes(elems) ;

                elems = GetIntegerSize(binr);
                DP = binr.ReadBytes(elems) ;

                elems = GetIntegerSize(binr);
                DQ = binr.ReadBytes(elems) ;

                elems = GetIntegerSize(binr);
                IQ = binr.ReadBytes(elems) ;

                Console.WriteLine("showing components ..");
                if (verbose) 
                        showBytes("nModulus", MODULUS) ;
                        showBytes("nExponent", E);
                        showBytes("nD", D);
                        showBytes("nP", P);
                        showBytes("nQ", Q);
                        showBytes("nDP", DP);
                        showBytes("nDQ", DQ);
                        showBytes("nIQ", IQ);
                

                // ------- create RSACryptoServiceProvider instance and initialize with public key -----
                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
                RSAParameters RSAparams = new RSAParameters();
                RSAparams.Modulus =MODULUS;
                RSAparams.Exponent = E;
                RSAparams.D = D;
                RSAparams.P = P;
                RSAparams.Q = Q;
                RSAparams.DP = DP;
                RSAparams.DQ = DQ;
                RSAparams.InverseQ = IQ;
                RSA.ImportParameters(RSAparams);
                return RSA;
        
        catch (Exception) 
                return null;
        
        finally 
                binr.Close();
        

valoraciones y reseñas

Si conservas alguna vacilación o capacidad de progresar nuestro tutorial eres capaz de añadir una anotación y con deseo lo leeremos.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *