2008-10-28 13 views
50

से एक पीईएम RSA निजी कुंजी को पढ़ने के लिए मैं PEM प्रारूप में एक RSA निजी कुंजी मिल गया है, वहाँ जो .NET से पढ़ सकते हैं और एक RSACryptoServiceProvider का दृष्टांत के लिए इसी जनता के साथ एन्क्रिप्टेड डाटा डिक्रिप्ट करने के लिए एक सीधे आगे रास्ता है कुंजी?कैसे नेट

उत्तर

41

मैंने हल किया, धन्यवाद। यदि किसी के भी दिलचस्पी है, 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)); 
+3

बाउंसीकैसल क्या है? – WildJoe

+37

@ विल्डजो: या तो राजाओं के लिए एक फुर्ती हुई आवास, या www.bouncycastle.org;) –

+1

पासवर्ड संरक्षित प्रमाण के साथ क्या? – Sinaesthetic

19

आप JavaScience'sOpenSSLKey के लिए स्रोत देख सकते हैं। (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(); 
     } 
} 
+0

कोशिश की, काम नहीं किया है, और अभी तक कोड के माध्यम से जाने के लिए समय नहीं लिया है, मुझे उम्मीद है कि एक आसान था उपाय। – Simone

+0

क्या आप असफल होने पर विवरण दे सकते हैं? मैंने कोड पर एक नज़र डाली, और ऐसा लगता है कि इसे काम करना चाहिए। शायद आप पीईएम फाइल भी पोस्ट कर सकते हैं? (यदि आपके पास एक संवेदनशील नहीं है)। –

+1

मुझे अभी यह जवाब [इस SO सवाल] से क्रॉस-लिंक मिला है (http://stackoverflow.com/a/1162519/12597)। अब जब मैं देखता हूं कि यह वास्तविक कोड फाइल है, और वे सचमुच एएसएन .1 एन्कोडेड डेटा को डीकोड कर रहे हैं, तो यह उत्तर अधिक +1 के योग्य है। (उन्हें वास्तव में खुद को 'जावासाइंस' नहीं कहना चाहिए) –

1

चेक http://msdn.microsoft.com/en-us/library/dd203099.aspx

क्रिप्टोग्राफी आवेदन ब्लॉक के तहत।

पता नहीं है कि आपको अपना जवाब मिल जाएगा, लेकिन यह एक कोशिश के लायक है।

टिप्पणी के बाद संपादित करें

ठीक है तो इस कोड को चेक करें।

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); 
} 
+0

नहीं, यह किसी भी असममित एल्गोरिदम का समर्थन नहीं करता है। – Simone

+1

यह कोड एक पीईएम आरएसए निजी कुंजी लोड नहीं कर सकता है, इसे उस कुंजी के आधार पर एक प्रमाणपत्र फ़ाइल की आवश्यकता है, जिसे उत्पन्न किया जा सकता है, लेकिन मैं उस चरण से बचना चाहता हूं। – Simone

+0

ठीक है, तो मुझे बताओ कि आपकी निजी कुंजी कहां है? –

4

-----BEGIN RSA PRIVATE KEY---- 

और

-----END RSA PRIVATE KEY----- 

के बीच सामान PKCS # 8 PrivateKeyInfo का बेस 64 एन्कोडिंग (जब तक यह कहते आरएसए एन्क्रिप्टेड निजी कुंजी जिस स्थिति में यह एक है EncryptedPrivateKeyInfo)।

मैन्युअल रूप से डीकोड करना मुश्किल नहीं है, लेकिन अन्यथा आपकी सबसे अच्छी शर्त 0/पर P/Invoke है।


अद्यतन:CryptImportPKCS8 समारोह नहीं रह गया है विंडोज सर्वर 2008 और Windows Vista के रूप में उपयोग के लिए उपलब्ध है। इसके बजाय, PFXImportCertStore फ़ंक्शन का उपयोग करें।

21
सम्मान के साथ

आसानी RSA निजी कुंजी आयात करने के लिए, इस तरह के BouncyCastle के रूप में 3 पार्टी कोड का उपयोग किए बिना, मुझे लगता है कि जवाब है: यह कोड है "नहीं, नहीं के साथ निजी कुंजी की एक पीईएम अकेले।"

हालांकि, जैसा कि सिमोन द्वारा उपरोक्त बताया गया है, आप केवल उस कुंजी (* .key) के पीईएम को उस कुंजी (* .crt) का उपयोग करके * .pfx फ़ाइल में जोड़ सकते हैं जो तब हो सकता है आसानी से आयात किया।

using System.Security.Cryptography.X509Certificates; 

X509Certificate2 combinedCertificate = new X509Certificate2(@"C:\path\to\file.pfx"); 

अब आप एन्क्रिप्ट करने के लिए MSDN से उदाहरण का अनुसरण कर सकते हैं:

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

तो जैसे नेट प्रमाणपत्र वर्ग के साथ सामान्य रूप से उपयोग:

कमांड लाइन से PFX फ़ाइल उत्पन्न करने के लिए और RSACryptoServiceProvider के माध्यम से डिक्रिप्टिंग:

मैंने छोड़ा कि डिक्रिप्ट करने के लिए आपको पीएफएक्स पासवर्ड और निर्यात करने योग्य फ़्लै का उपयोग करके आयात करने की आवश्यकता होगी जी। (देखें: 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); 
2

ठीक है, मैक का उपयोग कर इम मेरी स्वयं हस्ताक्षर किए कुंजी उत्पन्न करने के लिए। यहां उपयोग की जाने वाली कार्य विधि है।

मैंने अपनी मुख्य पीढ़ी को तेज करने के लिए एक शेल स्क्रिप्ट बनाई।

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 

जोड़ने + x स्क्रिप्ट के ध्वज को अंजाम

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 प्रमाणपत्र प्राप्त करने के लिए में डाल दिया।

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 और मोनो उपयोग कर रहा हूँ इस मार्ग जाना चाहती थी और मेरे पास कोई संकलित पुस्तकालयों या निर्भरता के साथ वेनिला फ्रेमवर्क कोड का उपयोग करना चाहता था।

इस के लिए मेरे अंतिम उपयोग मेरे ऐप

SslStream sslStream = new SslStream(serverCertificate, false, SslProtocols.Tls, true); 

मुझे आशा है कि यह अन्य लोगों को मदद मिलती करने के लिए टीसीपी संचार को सुरक्षित करने के SslStream था।

नोट

एक पासवर्ड मैं सही ढंग से निर्यात के लिए निजी कुंजी अनलॉक करने में असमर्थ था के बिना।

0

उन लोगों के लिए जो बाउंसी का उपयोग नहीं करना चाहते हैं, और अन्य उत्तरों में शामिल कोड में से कुछ को आजमा रहे हैं, मैंने पाया है कि कोड ज्यादातर समय काम करता है, लेकिन कुछ आरएसए निजी तारों पर यात्रा करता है, जैसा कि मैंने नीचे शामिल किया है। उछाल वाले कोड को देखकर, मैंने 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-----