У меня есть закрытый ключ RSA
в формате PEM
, есть ли прямой способ прочитать это из .NET и создать экземпляр RSACryptoServiceProvider
для дешифрования данных, зашифрованных с соответствующей публикацией ключ?Как прочитать закрытый ключ PEM RSA из .NET.
ответ
Я решил, спасибо. В случае, если кто-то заинтересован, bouncycastle сделал трюк, просто взял меня на некоторое время из-за недостатка знаний с моей стороны и документации. Это код:
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));
Вы можете взглянуть на JavaScience's источник для OpenSSLKey. (OpenSSLKey.cs)
Здесь есть код, который делает именно то, что вы хотите сделать.
На самом деле, у них много криптового кода available here.
Исходный фрагмент кода:
//------- 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();
}
}
Проверить http://msdn.microsoft.com/en-us/library/dd203099.aspx
под Cryptography Application Block.
Не знаю, получите ли вы ответ, но стоит попробовать.
Редактировать после комментариев.
Хорошо, тогда проверьте этот код.
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);
}
Материал между
-----BEGIN RSA PRIVATE KEY----
и
-----END RSA PRIVATE KEY-----
является base64 кодирование PKCS # 8 PrivateKeyInfo (если это не говорит RSA ENCRYPTED PRIVATE KEY в данном случае это EncryptedPrivateKeyInfo).
Это не так сложно декодировать вручную, но в противном случае ваш лучший выбор - P/Invoke to CryptImportPKCS8.
Update: Функция CryptImportPKCS8 больше не доступен для использования в качестве в Windows Server 2008 и Windows Vista. Вместо этого используйте функцию PFXImportCertStore.
Что касается легко импортировать закрытый ключ RSA, без использования 3-го коды партии, таких как BouncyCastle, я думаю, что ответ «Нет, не с PEM секретного ключа в одиночку.»
Однако, как указано выше, Simone, вы можете просто объединить PEM закрытого ключа (* .key) и файл сертификата с помощью этого ключа (* .crt) в файл * .pfx, который затем может быть легко импортировано.
Чтобы создать файл PFX из командной строки:
openssl pkcs12 -in a.crt -inkey a.key -export -out a.pfx
Затем используют обычно с .NET класса сертификатов, таких как:
using System.Security.Cryptography.X509Certificates;
X509Certificate2 combinedCertificate = new X509Certificate2(@"C:\path\to\file.pfx");
Теперь вы можете последовать примеру из MSDN для шифрования и дешифрование через RSACryptoServiceProvider:
Я решил, что для дешифрования вам потребуется импортировать с использованием пароля PFX и экспортируемого флага г. (см.: 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);
ОК, я использую mac для генерации своих самозанятых ключей. Вот мой рабочий метод.
Я создал сценарий оболочки для ускорения генерации ключа.
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
добавить + х выполнить флаг сценария
chmod +x genkey.sh
затем вызвать genkey.sh
./genkey.sh
Я ввожу пароль (важно, чтобы включить пароль, по крайней мере, для экспорта в конце)
Enter pass phrase for host.key:
Enter Export Password: {Important to enter a password here}
Verifying - Enter Export Password: { Same password here }
Я тогда взять все в Base64.Key и поместить его в строку с именем sslKey
private string sslKey = "MIIJiAIBA...................................." +
"......................ETC...................." +
"......................ETC...................." +
"......................ETC...................." +
".............ugICCAA=";
Затем я использовал ленивый поглотитель нагрузки недвижимости, чтобы получить мой X509 Cert с закрытым ключом.
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;
}
}
Я хотел пойти по этому пути, потому что я использую .net 2.0 и Mono на макинтош, и я хотел использовать ванильный Framework код без каких-либо скомпилированных библиотек или зависимостей.
Мое окончательное использование этого было SslStream, чтобы обеспечить TCP связь, чтобы мое приложение
SslStream sslStream = new SslStream(serverCertificate, false, SslProtocols.Tls, true);
Я надеюсь, что это поможет другим людям.
ПРИМЕЧАНИЕ
Без пароля я не смог правильно разблокировать секретный ключ для экспорта.
Для людей, которые не хотят использовать Bouncy, и пытаются использовать какой-либо код, включенный в другие ответы, я обнаружил, что код работает MOST того времени, но запускает некоторые частные строки RSA, такие как как тот, который я включил ниже. Глядя на пружинистом коде, я подправил код, предоставленный wprl в
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. не удалось прочитать закрытый ключ из файла .pem в с
- 2. Openssl convert .PEM, содержащий только закрытый ключ RSA .PKCS12
- 3. d2i_RSAPrivateKey не удается разобрать закрытый ключ RSA
- 4. Как преобразовать закрытый ключ в закрытый ключ RSA?
- 5. Импортировать закрытый ключ из файла pem в хранилище ключей
- 6. Как экспортировать закрытый ключ, зашифрованный в .pem-файле
- 7. Создайте закрытый ключ RSA из объекта String
- 8. Создать открытый/закрытый ключ RSA с OpenSSL?
- 9. HAProxy - не удалось загрузить SSL закрытый ключ из файла PEM
- 10. Как сгенерировать секретный ключ RSA из строки * pem в Java
- 11. Как импортировать закрытый ключ RSA, который сгенерирован openssl, в AndroidKeyStore
- 12. Flash SecureSocket и закрытый ключ RSA
- 13. Получить общедоступный и закрытый ключ из сертификата ASN1 зашифрованного pem
- 14. Erlang генерировать ключи RSA из PEM файлов
- 15. Загрузить закрытый ключ RSA с секретным ключом в Crypto ++
- 16. OpenSSL API Читайте закрытый ключ в DER формате вместо PEM
- 17. Преобразовать RSA PEM ключ Строка дер байт []
- 18. Как экспортировать закрытый ключ RSA в формат pem с помощью java
- 19. Как получить закрытый ключ из контейнера уровня RSA?
- 20. Thales Payshield HSM RSA Закрытый ключ
- 21. RSA Decryption в Android, используя закрытый ключ
- 22. нагрузки (OpenSSL генерироваться) DSA закрытый ключ из файла PEM
- 23. Извлечь открытый ключ из частного ключа в формате pem
- 24. Использовать существующий закрытый ключ PEM для подписи данных на iOS
- 25. SSL certifacte и закрытый ключ (RSA)
- 26. Создать закрытый ключ RSA с PKCS1
- 27. Как прочитать открытый ключ RSA из строки формата PEM с использованием API OpenSSL?
- 28. Как читать открытый ключ RSA в PEM + PKCS # 1 Формат
- 29. Где хранить закрытый ключ rsa в приложении загрузки весны
- 30. Как я могу конвертировать SSL-сертификат из PEM в DER и хранить закрытый ключ?
Пробовал, не работаю, и не торопитесь, чтобы пройти через код все же, я надеюсь, что было проще решение. – Simone 2008-10-28 15:22:54
Не могли бы вы рассказать о том, что не удалось? Я взглянул на код, и кажется, что он должен работать. Возможно, вы даже можете отправить PEM-файл? (Если у вас есть нечувствительный). – 2008-10-29 22:33:31
Я только что нашел этот ответ сшитым из [этого вопроса SO] (http://stackoverflow.com/a/1162519/12597). Теперь, когда я вижу, что это фактические файлы кода, и они буквально просто декодируют кодированные данные ASN.1, этот ответ заслуживает большего +1. (Они действительно не должны называть себя «JavaScience») – 2012-10-09 19:53:15