Tengo una clave privada RSA
en PEM
formato, ¿hay una manera directa de leer que a partir de .NET y una instancia de un RSACryptoServiceProvider
para descifrar los datos cifrados con el público correspondiente ¿llave?Cómo leer una clave privada RSA PEM de .NET
Respuesta
Lo he resuelto, gracias. En caso de que alguien esté interesado, bouncycastle hizo el truco, me tomó un tiempo debido a la falta de conocimiento por mi parte y la documentación. 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));
Puede echar un vistazo a JavaScience's fuente para OpenSSLKey. (OpenSSLKey.cs)
Hay un código que hace exactamente lo que quiere hacer.
De hecho, tienen una gran cantidad de código fuente criptográfico available here. código
Fuente fragmento:
//------- 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();
}
}
intentado, no funciona, y no se tomó el tiempo para pasar por el código, sin embargo, yo espero que había un sencillo solución. – Simone
¿Podría dar detalles sobre qué falló? Eché un vistazo al código y parece que debería funcionar. Tal vez incluso podría publicar el archivo PEM? (Si tiene uno no sensible). –
Acabo de encontrar esta respuesta reticulada de [esta pregunta SO] (http://stackoverflow.com/a/1162519/12597). Ahora que veo que se trata de archivos de código reales, y que literalmente están decodificando los datos codificados en ASN.1, esta respuesta merece más +1. (Realmente no deberían llamarse a sí mismos 'JavaScience') –
Comprobar http://msdn.microsoft.com/en-us/library/dd203099.aspx
bajo Criptografía bloque de aplicación.
No sé si obtendrás tu respuesta, pero vale la pena intentarlo.
Editar después del comentario.
Ok, entonces marque este código.
using System.Security.Cryptography;
public static string DecryptEncryptedData(stringBase64EncryptedData, stringPathToPrivateKeyFile) {
X509Certificate2 myCertificate;
try{
myCertificate = new X509Certificate2(PathToPrivateKeyFile);
} catch{
throw new CryptographicException("Unable to open key file.");
}
RSACryptoServiceProvider rsaObj;
if(myCertificate.HasPrivateKey) {
rsaObj = (RSACryptoServiceProvider)myCertificate.PrivateKey;
} else
throw new CryptographicException("Private key not contained within certificate.");
if(rsaObj == null)
return String.Empty;
byte[] decryptedBytes;
try{
decryptedBytes = rsaObj.Decrypt(Convert.FromBase64String(Base64EncryptedData), false);
} catch {
throw new CryptographicException("Unable to decrypt data.");
}
// Check to make sure we decrpyted the string
if(decryptedBytes.Length == 0)
return String.Empty;
else
return System.Text.Encoding.UTF8.GetString(decryptedBytes);
}
Las cosas entre el
-----BEGIN RSA PRIVATE KEY----
y
-----END RSA PRIVATE KEY-----
es la codificación base64 de un PKCS # 8 PrivateKeyInfo (a menos que diga RSA clave cifrada PRIVADO en cuyo caso se trata de una EncryptedPrivateKeyInfo).
No es tan difícil decodificar manualmente, pero de lo contrario su mejor opción es P/Invocar a CryptImportPKCS8.
Actualización: La función CryptImportPKCS8 ya no está disponible para su uso como de Windows Server 2008 y Windows Vista. En su lugar, use la función PFXImportCertStore.
Con respecto a la importación fácilmente la clave privada RSA, sin necesidad de utilizar código de tercera parte, como BouncyCastle, creo que la respuesta es "No, no con un PEM de la clave privada solo."
Sin embargo, como se mencionó anteriormente por Simone, simplemente puede combinar el PEM de la clave privada (* .key) y el archivo de certificado utilizando esa clave (* .crt) en un archivo * .pfx que luego puede ser fácilmente importado
para generar el archivo PFX desde la línea de comandos:
openssl pkcs12 -in a.crt -inkey a.key -export -out a.pfx
A continuación, utilice normalmente con el certificado clase .NET tales como:
using System.Security.Cryptography.X509Certificates;
X509Certificate2 combinedCertificate = new X509Certificate2(@"C:\path\to\file.pfx");
Ahora se puede seguir el ejemplo de MSDN para cifrar y descifrado a través de RSACryptoServiceProvider:
Dejé claro que para descifrar necesitaría importar usando la contraseña PFX y la Fla exportable gramo. (Ver: BouncyCastle RSAPrivateKey to .NET RSAPrivateKey)
X509KeyStorageFlags flags = X509KeyStorageFlags.Exportable;
X509Certificate2 cert = new X509Certificate2("my.pfx", "somepass", flags);
RSACryptoServiceProvider rsa = (RSACryptoServiceProvider)cert.PrivateKey;
RSAParameters rsaParam = rsa.ExportParameters(true);
bien, Im usando mac para generar claves firmadas mi auto. Aquí está el método de trabajo que utilicé.
Creé un script de shell para acelerar la generación de mi clave.
genkey.sh
#/bin/sh
ssh-keygen -f host.key
openssl req -new -key host.key -out request.csr
openssl x509 -req -days 99999 -in request.csr -signkey host.key -out server.crt
openssl pkcs12 -export -inkey host.key -in server.crt -out private_public.p12 -name "SslCert"
openssl base64 -in private_public.p12 -out Base64.key
añadir el + x ejecutar bandera para el guión
chmod +x genkey.sh
luego llamar genkey.sh
./genkey.sh
entro una contraseña (importante incluir una contraseña al menos para la exportación al final)
Enter pass phrase for host.key:
Enter Export Password: {Important to enter a password here}
Verifying - Enter Export Password: { Same password here }
entonces tomo todo en Base64.Key y lo puse en una cadena denominada SslKey
private string sslKey = "MIIJiAIBA...................................." +
"......................ETC...................." +
"......................ETC...................." +
"......................ETC...................." +
".............ugICCAA=";
Luego utiliza un captador de carga perezosa de propiedades para conseguir mi X509 Cert con una clave privada.
X509Certificate2 _serverCertificate = null;
X509Certificate2 serverCertificate{
get
{
if (_serverCertificate == null){
string pass = "Your Export Password Here";
_serverCertificate = new X509Certificate(Convert.FromBase64String(sslKey), pass, X509KeyStorageFlags.Exportable);
}
return _serverCertificate;
}
}
quería ir esta ruta porque estoy utilizando .NET 2.0 y Mono en mac y quería usar el código de Marco de vainilla con ninguna biblioteca o dependencias compiladas.
Mi uso final de esto fue la SslStream para asegurar la comunicación TCP para mi aplicación
SslStream sslStream = new SslStream(serverCertificate, false, SslProtocols.Tls, true);
espero que esto ayuda a otras personas.
NOTA
Sin una contraseña he podido abrir correctamente la clave privada para la exportación.
Para las personas que no quieren usar Bouncy, y están probando parte del código incluido en otras respuestas, he descubierto que el código funciona la MAYORÍA del tiempo, pero se activa en algunas cadenas privadas de RSA, tales como el que he incluido a continuación. Al observar el código hinchable, pellizqué el código proporcionado por wprl a
RSAparams.D = ConvertRSAParametersField(D, MODULUS.Length);
RSAparams.DP = ConvertRSAParametersField(DP, P.Length);
RSAparams.DQ = ConvertRSAParametersField(DQ, Q.Length);
RSAparams.InverseQ = ConvertRSAParametersField(IQ, Q.Length);
private static byte[] ConvertRSAParametersField(byte[] bs, int size)
{
if (bs.Length == size)
return bs;
if (bs.Length > size)
throw new ArgumentException("Specified size too small", "size");
byte[] padded = new byte[size];
Array.Copy(bs, 0, padded, size - bs.Length, bs.Length);
return padded;
}
-----BEGIN RSA PRIVATE KEY-----
MIIEoQIBAAKCAQEAxCgWAYJtfKBVa6Px1Blrj+3Wq7LVXDzx+MiQFrLCHnou2Fvb
fxuDeRmd6ERhDWnsY6dxxm981vTlXukvYKpIZQYpiSzL5pyUutoi3yh0+/dVlsHZ
UHheVGZjSMgUagUCLX1p/augXltAjgblUsj8GFBoKJBr3TMKuR5TwF7lBNYZlaiR
k9MDZTROk6MBGiHEgD5RaPKA/ot02j3CnSGbGNNubN2tyXXAgk8/wBmZ4avT0U4y
5oiO9iwCF/Hj9gK/S/8Q2lRsSppgUSsCioSg1CpdleYzIlCB0li1T0flB51zRIpg
JhWRfmK1uTLklU33xfzR8zO2kkfaXoPTHSdOGQIDAQABAoIBAAkhfzoSwttKRgT8
sgUYKdRJU0oqyO5s59aXf3LkX0+L4HexzvCGbK2hGPihi42poJdYSV4zUlxZ31N2
XKjjRFDE41S/Vmklthv8i3hX1G+Q09XGBZekAsAVrrQfRtP957FhD83/GeKf3MwV
Bhe/GKezwSV3k43NvRy2N1p9EFa+i7eq1e5i7MyDxgKmja5YgADHb8izGLx8Smdd
+v8EhWkFOcaPnQRj/LhSi30v/CjYh9MkxHMdi0pHMMCXleiUK0Du6tnsB8ewoHR3
oBzL4F5WKyNHPvesYplgTlpMiT0uUuN8+9Pq6qsdUiXs0wdFYbs693mUMekLQ4a+
1FOWvQECgYEA7R+uI1r4oP82sTCOCPqPi+fXMTIOGkN0x/1vyMXUVvTH5zbwPp9E
0lG6XmJ95alMRhjvFGMiCONQiSNOQ9Pec5TZfVn3M/w7QTMZ6QcWd6mjghc+dGGE
URmCx8xaJb847vACir7M08AhPEt+s2C7ZokafPCoGe0qw/OD1fLt3NMCgYEA08WK
S+G7dbCvFMrBP8SlmrnK4f5CRE3pV4VGneWp/EqJgNnWwaBCvUTIegDlqS955yVp
q7nVpolAJCmlUVmwDt4gHJsWXSQLMXy3pwQ25vdnoPe97y3xXsi0KQqEuRjD1vmw
K7SXoQqQeSf4z74pFal4CP38U3pivvoE4MQmJeMCfyJFceWqQEUEneL+IYkqrZSK
7Y8urNse5MIC3yUlcose1cWVKyPh4RCEv2rk0U1gKqX29Jb9vO2L7RflAmrLNFuA
J+72EcRxsB68RAJqA9VHr1oeAejQL0+JYF2AK4dJG/FsvvFOokv4eNU+FBHY6Tzo
k+t63NDidkvb5jIF6lsCgYEAlnQ08f5Y8Z9qdCosq8JpKYkwM+kxaVe1HUIJzqpZ
X24RTOL3aa8TW2afy9YRVGbvg6IX9jJcMSo30Llpw2cl5xo21Dv24ot2DF2gGN+s
peFF1Z3Naj1Iy99p5/KaIusOUBAq8pImW/qmc/1LD0T56XLyXekcuK4ts6Lrjkit
FaMCgYAusOLTsRgKdgdDNI8nMQB9iSliwHAG1TqzB56S11pl+fdv9Mkbo8vrx6g0
NM4DluCGNEqLZb3IkasXXdok9e8kmX1en1lb5GjyPbc/zFda6eZrwIqMX9Y68eNR
IWDUM3ckwpw3rcuFXjFfa+w44JZVIsgdoGHiXAdrhtlG/i98Rw==
-----END RSA PRIVATE KEY-----
- 1. Convertir clave privada tradicional PEM a clave privada PKCS8
- 2. Cargue la clave RSA privada codificada PEM en Crypto ++
- 3. Abrir una clave privada RSA de Ruby
- 4. ¿Cómo convierto una clave XML RSA en un archivo PEM?
- 5. Cómo leer una clave pública RSA en PEM + PKCS # 1 formato
- 6. Desencriptando con clave privada del archivo .pem en C# con .NET crypto library
- 7. Encriptación con clave privada RSA en Java
- 8. Openssl convert .PEM que solo contiene clave privada RSA para .PKCS12
- 9. Generar clave privada RSA en C#
- 10. Lectura de PEM Clave pública de RSA Solo usando Bouncy Castle
- 11. Uso de una clave pública de RSA para descifrar una cadena cifrada con la clave privada de RSA
- 12. ¿Cómo leer una clave privada para usar con OpenSAML?
- 13. Flash SecureSocket y la clave privada de RSA
- 14. Cómo cargar la clave privada RSA desde el archivo
- 15. ¿Cómo leer una clave privada del archivo pvk en C#?
- 16. .NET Private Key Rsa Cifrado
- 17. C++ clave privada de exportación OpenSSL
- 18. Encriptación de una clave privada con BouncyCastle
- 19. Tengo módulo y exponente privado. ¿Cómo construir una clave privada RSA y firmar un mensaje?
- 20. ¿Cómo generar un KeyPair de RSA con una clave privada encriptada con contraseña?
- 21. Dada una clave privada, ¿es posible derivar su clave pública?
- 22. Firme un archivo usando una clave privada en .NET
- 23. Cómo convertir la clave privada PEM PKCS con formato 8 al formato tradicional?
- 24. cifrar y descifrar una cadena de texto con RSA y DES3 clave
- 25. ¿Cómo funciona la frase de contraseña de clave privada de RSA bajo el capó?
- 26. Convertir clave pública RSA a RSA DER
- 27. Excepción de "clave incorrecta" para certificados con clave privada exportable
- 28. firma de una cadena con la clave privada RSA en Google App Engine SDK Python
- 29. ¿Cómo podemos convertir una cadena de PEM a Der formato
- 30. Encriptación con la aplicación clave pública/privada en .net
¿Qué es bouncycastle? – WildJoe
@WildJoe: O bien un hábitat inflado para monarcas, o www.bouncycastle.org;) –
¿qué tal con un certificado protegido con contraseña? – Sinaesthetic