문제

나는있다 RSA 개인 키 PEM 형식, .NET에서 그것을 읽고 인스턴스화하는 간단한 방법이 있습니까? RSACryptoServiceProvider 해당 공개 키와 암호화 된 데이터를 암호화하려면?

도움이 되었습니까?

해결책

고마워요. 누구나 관심이있는 경우 바운시 캐슬 트릭을했는데, 내 편과 문서의 지식 부족으로 인해 시간이 걸렸습니다. 이것은 코드입니다.

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

다른 팁

Bouncycastle과 같은 제 3 자 코드를 사용하지 않고 RSA 개인 키를 쉽게 가져 오는 것과 관련하여, 나는 대답이 "개인 키의 PEM이 아니라"라고 생각합니다.

그러나 Simone이 위에서 언급 한 것처럼 개인 키 (*.key)의 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 비밀번호와 내보낼 수있는 플래그를 사용하여 가져와야합니다. (보다: .net rsaprivatekey에서 Bouncycastle rsaprivatekey)

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

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

당신은 살펴볼 수 있습니다 Javascience 's 소스 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----- 

PKCS#8 PrivateKeyInfo의 Base64 인코딩입니다 (RSA가 암호화 된 개인 키가 표시되지 않는 한 암호화 된 프리 테 키인포가 표시되지 않는 한).

수동으로 디코딩하는 것은 그리 어렵지 않지만 그렇지 않으면 가장 좋은 방법은 p/호출입니다. cryptimportpkcs8.


업데이트: 그만큼 cryptimportpkcs8 Windows Server 2008 및 Windows Vista에서는 기능을 더 이상 사용할 수 없습니다. 대신 사용하십시오 pfximportCertStore 기능.

자, 자체 서명 키를 생성하기 위해 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

스크립트에 +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=";

그런 다음 게으른로드 속성 getter를 사용하여 개인 키로 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;
    }
}

Mac에서 .NET 2.0 및 mono를 사용하고 있기 때문에이 경로로 가고 싶었고 컴파일 된 라이브러리 나 종속성이없는 바닐라 프레임 워크 코드를 사용하고 싶었습니다.

이것에 대한 나의 마지막 사용은 내 앱에 TCP 커뮤니케이션을 보호하기위한 sslstream이었습니다.

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

탄력을 사용하고 싶지 않고 다른 답변에 포함 된 코드 중 일부를 시도하는 사람들을 위해 코드가 대부분 작동한다는 것을 알았지 만 I와 같은 RSA 비공개 문자열을 여행합니다. 'VE는 아래에 포함되어 있습니다. 탄력 코드를 살펴보면 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 라이브러리를 만들었습니다. 코드는 사용할 수 있습니다 github 그리고 설치할 수 있습니다 너겟:

PM> Install-Package PemUtils

또는 DER 변환기 만 원한다면 :

PM> Install-Package DerConverter

PEM 데이터에서 RSA 키를 읽기위한 사용 :

using (var stream = File.OpenRead(path))
using (var reader = new PemReader(stream))
{
    var rsaParameters = reader.ReadRsaKey();
    // ...
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top