Movatterモバイル変換


[0]ホーム

URL:


Skip to content
Search Gists
Sign in Sign up

Instantly share code, notes, and snippets.

@valep27
Forked fromtherightstuff/RSAKeys.cs
CreatedDecember 13, 2017 09:44
    • Star(4)You must be signed in to star a gist
    • Fork(0)You must be signed in to fork a gist
    Save valep27/4a720c25b35fff83fbf872516f847863 to your computer and use it in GitHub Desktop.
    Import and export RSA Keys between C# and PEM format using BouncyCastle
    usingOrg.BouncyCastle.Crypto;
    usingOrg.BouncyCastle.Crypto.Parameters;
    usingOrg.BouncyCastle.OpenSsl;
    usingOrg.BouncyCastle.Security;
    usingSystem;
    usingSystem.IO;
    usingSystem.Security.Cryptography;
    namespaceMyProject.Data.Encryption
    {
    publicclassRSAKeys
    {
    /// <summary>
    /// Import OpenSSH PEM private key string into MS RSACryptoServiceProvider
    /// </summary>
    /// <param name="pem"></param>
    /// <returns></returns>
    publicstaticRSACryptoServiceProviderImportPrivateKey(stringpem){
    PemReaderpr=newPemReader(newStringReader(pem));
    AsymmetricCipherKeyPairKeyPair=(AsymmetricCipherKeyPair)pr.ReadObject();
    RSAParametersrsaParams=DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)KeyPair.Private);
    RSACryptoServiceProvidercsp=newRSACryptoServiceProvider();// cspParams);
    csp.ImportParameters(rsaParams);
    returncsp;
    }
    /// <summary>
    /// Import OpenSSH PEM public key string into MS RSACryptoServiceProvider
    /// </summary>
    /// <param name="pem"></param>
    /// <returns></returns>
    publicstaticRSACryptoServiceProviderImportPublicKey(stringpem){
    PemReaderpr=newPemReader(newStringReader(pem));
    AsymmetricKeyParameterpublicKey=(AsymmetricKeyParameter)pr.ReadObject();
    RSAParametersrsaParams=DotNetUtilities.ToRSAParameters((RsaKeyParameters)publicKey);
    RSACryptoServiceProvidercsp=newRSACryptoServiceProvider();// cspParams);
    csp.ImportParameters(rsaParams);
    returncsp;
    }
    /// <summary>
    /// Export private (including public) key from MS RSACryptoServiceProvider into OpenSSH PEM string
    /// slightly modified from https://stackoverflow.com/a/23739932/2860309
    /// </summary>
    /// <param name="csp"></param>
    /// <returns></returns>
    publicstaticstringExportPrivateKey(RSACryptoServiceProvidercsp)
    {
    StringWriteroutputStream=newStringWriter();
    if(csp.PublicOnly)thrownewArgumentException("CSP does not contain a private key","csp");
    varparameters=csp.ExportParameters(true);
    using(varstream=newMemoryStream())
    {
    varwriter=newBinaryWriter(stream);
    writer.Write((byte)0x30);// SEQUENCE
    using(varinnerStream=newMemoryStream())
    {
    varinnerWriter=newBinaryWriter(innerStream);
    EncodeIntegerBigEndian(innerWriter,newbyte[]{0x00});// Version
    EncodeIntegerBigEndian(innerWriter,parameters.Modulus);
    EncodeIntegerBigEndian(innerWriter,parameters.Exponent);
    EncodeIntegerBigEndian(innerWriter,parameters.D);
    EncodeIntegerBigEndian(innerWriter,parameters.P);
    EncodeIntegerBigEndian(innerWriter,parameters.Q);
    EncodeIntegerBigEndian(innerWriter,parameters.DP);
    EncodeIntegerBigEndian(innerWriter,parameters.DQ);
    EncodeIntegerBigEndian(innerWriter,parameters.InverseQ);
    varlength=(int)innerStream.Length;
    EncodeLength(writer,length);
    writer.Write(innerStream.GetBuffer(),0,length);
    }
    varbase64=Convert.ToBase64String(stream.GetBuffer(),0,(int)stream.Length).ToCharArray();
    // WriteLine terminates with \r\n, we want only \n
    outputStream.Write("-----BEGIN RSA PRIVATE KEY-----\n");
    // Output as Base64 with lines chopped at 64 characters
    for(vari=0;i<base64.Length;i+=64)
    {
    outputStream.Write(base64,i,Math.Min(64,base64.Length-i));
    outputStream.Write("\n");
    }
    outputStream.Write("-----END RSA PRIVATE KEY-----");
    }
    returnoutputStream.ToString();
    }
    /// <summary>
    /// Export public key from MS RSACryptoServiceProvider into OpenSSH PEM string
    /// slightly modified from https://stackoverflow.com/a/28407693
    /// </summary>
    /// <param name="csp"></param>
    /// <returns></returns>
    publicstaticstringExportPublicKey(RSACryptoServiceProvidercsp)
    {
    StringWriteroutputStream=newStringWriter();
    varparameters=csp.ExportParameters(false);
    using(varstream=newMemoryStream())
    {
    varwriter=newBinaryWriter(stream);
    writer.Write((byte)0x30);// SEQUENCE
    using(varinnerStream=newMemoryStream())
    {
    varinnerWriter=newBinaryWriter(innerStream);
    innerWriter.Write((byte)0x30);// SEQUENCE
    EncodeLength(innerWriter,13);
    innerWriter.Write((byte)0x06);// OBJECT IDENTIFIER
    varrsaEncryptionOid=newbyte[]{0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01};
    EncodeLength(innerWriter,rsaEncryptionOid.Length);
    innerWriter.Write(rsaEncryptionOid);
    innerWriter.Write((byte)0x05);// NULL
    EncodeLength(innerWriter,0);
    innerWriter.Write((byte)0x03);// BIT STRING
    using(varbitStringStream=newMemoryStream())
    {
    varbitStringWriter=newBinaryWriter(bitStringStream);
    bitStringWriter.Write((byte)0x00);// # of unused bits
    bitStringWriter.Write((byte)0x30);// SEQUENCE
    using(varparamsStream=newMemoryStream())
    {
    varparamsWriter=newBinaryWriter(paramsStream);
    EncodeIntegerBigEndian(paramsWriter,parameters.Modulus);// Modulus
    EncodeIntegerBigEndian(paramsWriter,parameters.Exponent);// Exponent
    varparamsLength=(int)paramsStream.Length;
    EncodeLength(bitStringWriter,paramsLength);
    bitStringWriter.Write(paramsStream.GetBuffer(),0,paramsLength);
    }
    varbitStringLength=(int)bitStringStream.Length;
    EncodeLength(innerWriter,bitStringLength);
    innerWriter.Write(bitStringStream.GetBuffer(),0,bitStringLength);
    }
    varlength=(int)innerStream.Length;
    EncodeLength(writer,length);
    writer.Write(innerStream.GetBuffer(),0,length);
    }
    varbase64=Convert.ToBase64String(stream.GetBuffer(),0,(int)stream.Length).ToCharArray();
    // WriteLine terminates with \r\n, we want only \n
    outputStream.Write("-----BEGIN PUBLIC KEY-----\n");
    for(vari=0;i<base64.Length;i+=64)
    {
    outputStream.Write(base64,i,Math.Min(64,base64.Length-i));
    outputStream.Write("\n");
    }
    outputStream.Write("-----END PUBLIC KEY-----");
    }
    returnoutputStream.ToString();
    }
    /// <summary>
    /// https://stackoverflow.com/a/23739932/2860309
    /// </summary>
    /// <param name="stream"></param>
    /// <param name="length"></param>
    privatestaticvoidEncodeLength(BinaryWriterstream,intlength)
    {
    if(length<0)thrownewArgumentOutOfRangeException("length","Length must be non-negative");
    if(length<0x80)
    {
    // Short form
    stream.Write((byte)length);
    }
    else
    {
    // Long form
    vartemp=length;
    varbytesRequired=0;
    while(temp>0)
    {
    temp>>=8;
    bytesRequired++;
    }
    stream.Write((byte)(bytesRequired|0x80));
    for(vari=bytesRequired-1;i>=0;i--)
    {
    stream.Write((byte)(length>>(8*i)&0xff));
    }
    }
    }
    /// <summary>
    /// https://stackoverflow.com/a/23739932/2860309
    /// </summary>
    /// <param name="stream"></param>
    /// <param name="value"></param>
    /// <param name="forceUnsigned"></param>
    privatestaticvoidEncodeIntegerBigEndian(BinaryWriterstream,byte[]value,boolforceUnsigned=true)
    {
    stream.Write((byte)0x02);// INTEGER
    varprefixZeros=0;
    for(vari=0;i<value.Length;i++)
    {
    if(value[i]!=0)break;
    prefixZeros++;
    }
    if(value.Length-prefixZeros==0)
    {
    EncodeLength(stream,1);
    stream.Write((byte)0);
    }
    else
    {
    if(forceUnsigned&&value[prefixZeros]>0x7f)
    {
    // Add a prefix zero to force unsigned if the MSB is 1
    EncodeLength(stream,value.Length-prefixZeros+1);
    stream.Write((byte)0);
    }
    else
    {
    EncodeLength(stream,value.Length-prefixZeros);
    }
    for(vari=prefixZeros;i<value.Length;i++)
    {
    stream.Write(value[i]);
    }
    }
    }
    }
    }
    Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

    [8]ページ先頭

    ©2009-2025 Movatter.jp