سؤال

لقد حصلت على RSA المفتاح الخاص في PEM هل هناك طريقة مباشرة لقراءة ذلك من .NET وإنشاء مثيل له RSACryptoServiceProvider لفك تشفير البيانات المشفرة بالمفتاح العام المقابل؟

هل كانت مفيدة؟

المحلول

وأنا حلها، وذلك بفضل. في حالة أي شخص مهتم، 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)); 

نصائح أخرى

وفيما يتعلق المستوردة بسهولة المفتاح الخاص RSA، من دون استخدام كود 3rd الطرف مثل BouncyCastle، وأعتقد أن الجواب هو "لا، ليس مع PEM من المفتاح الخاص وحده."

ولكن، وكما ألمح إليها أعلاه من قبل سيمون، يمكنك ببساطة الجمع بين PEM من المفتاح الخاص (* يتضمن المنتج) وملف الشهادة باستخدام هذا المفتاح (* بامتداد 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 إلى صافي RSAPrivateKey )

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

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

وقد نلقي نظرة على مصدر JavaScience ل<لأ href = "HTTPS: // جوهر. github.com/njmube/edc64bb2f7599d33ca5a "يختلط =" نوفولو noreferrer "> OpenSSLKey

وهناك قانون في هناك أن يفعل بالضبط ما تريد القيام به.

في الواقع، لديهم الكثير من التعليمات البرمجية المصدر التشفير متاح هنا .


وشفرة المصدر المتكررة:

//------- 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();
        }
}

الاشياء بين

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

و

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

هو ترميز base64 لـ PKCS#8 PrivateKeyInfo (ما لم يُذكر RSA ENCRYPTED PRIVATE KEY وفي هذه الحالة يكون EncryptedPrivateKeyInfo).

ليس من الصعب فك التشفير يدويًا، ولكن بخلاف ذلك فإن أفضل رهان لك هو P/Invoce to كريبتيمبورتPKCS8.


تحديث: ال كريبتيمبورتPKCS8 لم تعد الوظيفة متاحة للاستخدام اعتبارًا من Windows Server 2008 وWindows Vista.بدلاً من ذلك، استخدم PFXImportCertStore وظيفة.

وطيب، والدردشة باستخدام ماك لتوليد بلدي موقعة ذاتيا المفاتيح. هنا هو أسلوب العمل استعملتها.

وأنا خلقت شيل لتسريع جيلي رئيسي.

و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 سيرت مع مفتاح خاص.

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;
    }
}

وكنت أرغب في السير في هذا الطريق لأنني أستخدمه صافي 2.0 ومونو لجنة الهدنة العسكرية، وأردت أن استخدام رمز الإطار الفانيليا مع عدم وجود مكتبات المترجمة أو التبعيات.

وكان استخدامي النهائي لهذا SslStream لتأمين الاتصالات TCP إلى التطبيق الخاص بي

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

وآمل أن يساعد هذا أشخاص آخرين.

<قوية> ملاحظة

وبدون كلمة مرور لم أتمكن من فتح المفتاح الخاص للتصدير بشكل صحيح.

يفحص 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); 
} 

وبالنسبة للأشخاص الذين لا يريدون لاستخدام نطاط، وتحاول بعض من قانون المدرجة في إجابات أخرى، لقد وجدت أن رمز يعمل أكثر من مرة، ولكن الرحلات على بعض سلاسل خاصة 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-----

ولقد أنشأ مكتبة PemUtils أن يفعل ذلك بالضبط. رمز متاح في جيثب ويمكن تركيبها من <لأ href = "HTTPS: // www.nuget.org/packages؟q=pemutils "يختلط =" نوفولو noreferrer "> NuGet :

PM> Install-Package PemUtils

وأو إذا كنت تريد فقط تحويل DER:

PM> Install-Package DerConverter

والاستخدام لقراءة مفتاح RSA من البيانات PEM:

using (var stream = File.OpenRead(path))
using (var reader = new PemReader(stream))
{
    var rsaParameters = reader.ReadRsaKey();
    // ...
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top