RSA密钥转换问题

lingrain 2014-10-25 11:04:02
密钥是用C#类库生成的XML格式,
要转成JS下能使用的密钥PEM格式,
最好能互转,详见后附示例说明。

谢谢~

附:

C#生成的私钥(XML):
<RSAKeyValue><Modulus>ww7D0rNm47u+lpe0RmQfZJ5c81LT1yVQjrwPh8V2KYeN1ukSNtQcxXR0up0sOeswtdR2K91FHxY+W2LbBDmB7VvlSbeRCu5UuAVP5N6bGjrXmMxG0TL8eeN+lCfCkIEMppxvcPC+yodxGrSz8LsK/pIkwktQucIwV6136GoceIc=</Modulus><Exponent>AQAB</Exponent><P>8X6BRa4AyPlpSXZhSmbSxoEMFkK1wKkRti2y2AxuHPQ3EJHTw6c4qpvlHAYH0j/duOiHUzFxJaN95zD7qWMBOQ==</P><Q>zsYy1hF7m5+2hMhwwb/Mn/dUp97kfky1H1iboxg62ULnLC/w4e8+/T8+xoF4TNMJTXllL7LEZjRfmctBE+YHvw==</Q><DP>62Nrjge1LDAvuDNzUZo4CNTweyI7Fre1U+XnVT+IdSB2K+h4iVUNnv6lq1MVfJJUBFBi12xx5UYfCqJsKwcdwQ==</DP><DQ>WfUgaMFyZWI2pc4OQDyRaYbQ7beq8MeuhNSn4WzJLXxN1ouE4MaVQNgjF3l8PPATPAF0ZCwCBfUDIoWq6l1JQQ==</DQ><InverseQ>SwxDBI/2cCam37QQ4X3TXRh2gj8rCgz9xCbmtJaFzFQdEn+QCPPHpxsf1sc0HzIeBk4fgHm0jpXbtciqIUX/Cw==</InverseQ><D>q90GjU+lCGMTunxQSvVM88rU+0+vd5FZOWpaBLbnNhBJ2WHiuoyKDTBe6U4y+ZVQheV9eYisrodaygqAD2jcIEwvYaK5MW4J7EQYtwzXtKIKg8ly4MiCXqGgb0N4ndql6lLjIzvVe6+k4qSso0vJfHWYZeUCODvqGTu4e7r7UQE=</D></RSAKeyValue>

JS下的PEM密钥格式(PEM):
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQDRhGF7X4A0ZVlEg594WmODVVUIiiPQs04aLmvfg8SborHss5gQ
Xu0aIdUT6nb5rTh5hD2yfpF2WIW6M8z0WxRhwicgXwi80H1aLPf6lEPPLvN29EhQ
NjBpkFkAJUbS8uuhJEeKw0cE49g80eBBF4BCqSL6PFQbP9/rByxdxEoAIQIDAQAB
AoGAA9/q3Zk6ib2GFRpKDLO/O2KMnAfR+b4XJ6zMGeoZ7Lbpi3MW0Nawk9ckVaX0
ZVGqxbSIX5Cvp/yjHHpww+QbUFrw/gCjLiiYjM9E8C3uAF5AKJ0r4GBPl4u8K4bp
bXeSxSB60/wPQFiQAJVcA5xhZVzqNuF3EjuKdHsw+dk+dPECQQDubX/lVGFgD/xY
uchz56Yc7VHX+58BUkNSewSzwJRbcueqknXRWwj97SXqpnYfKqZq78dnEF10SWsr
/NMKi+7XAkEA4PVqDv/OZAbWr4syXZNv/Mpl4r5suzYMMUD9U8B2JIRnrhmGZPzL
x23N9J4hEJ+Xh8tSKVc80jOkrvGlSv+BxwJAaTOtjA3YTV+gU7Hdza53sCnSw/8F
YLrgc6NOJtYhX9xqdevbyn1lkU0zPr8mPYg/F84m6MXixm2iuSz8HZoyzwJARi2p
aYZ5/5B2lwroqnKdZBJMGKFpUDn7Mb5hiSgocxnvMkv6NjT66Xsi3iYakJII9q8C
Ma1qZvT/cigmdbAh7wJAQNXyoizuGEltiSaBXx4H29EdXNYWDJ9SS5f070BRbAIl
dqRh3rcNvpY6BKJqFapda1DjdcncZECMizT/GMrc1w==
-----END RSA PRIVATE KEY-----
...全文
3155 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_27302885 2016-11-15
  • 打赏
  • 举报
回复
为什么我私钥pem转xml的时候,如下图这句报不正确的数据,何解
oldleft_hxb 2015-10-09
  • 打赏
  • 举报
回复
请问5楼高手,公钥pem转xml的代码有吗?
  • 打赏
  • 举报
回复
引用 4 楼 dk8705 的回复:
原来是我转了公钥才报错。
转公钥用

public static String ExportPublicKeyToPEMFormat(RSACryptoServiceProvider csp)
{
    TextWriter outputStream = new StringWriter();

    var parameters = csp.ExportParameters(false);
    using (var stream = new MemoryStream())
    {
        var writer = new BinaryWriter(stream);
        writer.Write((byte)0x30); // SEQUENCE
        using (var innerStream = new MemoryStream())
        {
            var innerWriter = new BinaryWriter(innerStream);
            EncodeIntegerBigEndian(innerWriter, new byte[] { 0x00 }); // Version
            EncodeIntegerBigEndian(innerWriter, parameters.Modulus);
            EncodeIntegerBigEndian(innerWriter, parameters.Exponent);

            //All Parameter Must Have Value so Set Other Parameter Value Whit Invalid Data  (for keeping Key Structure  use "parameters.Exponent" value for invalid data)
            EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.D
            EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.P
            EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.Q
            EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.DP
            EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.DQ
            EncodeIntegerBigEndian(innerWriter, parameters.Exponent); // instead of parameters.InverseQ

            var length = (int)innerStream.Length;
            EncodeLength(writer, length);
            writer.Write(innerStream.GetBuffer(), 0, length);
        }

        var base64 = Convert.ToBase64String(stream.GetBuffer(), 0, (int)stream.Length).ToCharArray();
        outputStream.WriteLine("-----BEGIN PUBLIC KEY-----");
        // Output as Base64 with lines chopped at 64 characters
        for (var i = 0; i < base64.Length; i += 64)
        {
            outputStream.WriteLine(base64, i, Math.Min(64, base64.Length - i));
        }
        outputStream.WriteLine("-----END PUBLIC KEY-----");

        return outputStream.ToString();

    }
}

private static void EncodeIntegerBigEndian(BinaryWriter stream, byte[] value, bool forceUnsigned = true)
{
    stream.Write((byte)0x02); // INTEGER
    var prefixZeros = 0;
    for (var i = 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 (var i = prefixZeros; i < value.Length; i++)
        {
            stream.Write(value[i]);
        }
    }
}

private static void EncodeLength(BinaryWriter stream, int length)
{
    if (length < 0) throw new ArgumentOutOfRangeException("length", "Length must be non-negative");
    if (length < 0x80)
    {
        // Short form
        stream.Write((byte)length);
    }
    else
    {
        // Long form
        var temp = length;
        var bytesRequired = 0;
        while (temp > 0)
        {
            temp >>= 8;
            bytesRequired++;
        }
        stream.Write((byte)(bytesRequired | 0x80));
        for (var i = bytesRequired - 1; i >= 0; i--)
        {
            stream.Write((byte)(length >> (8 * i) & 0xff));
        }
    }
}
闪电001 2015-06-12
  • 打赏
  • 举报
回复
原来是我转了公钥才报错。
闪电001 2015-06-12
  • 打赏
  • 举报
回复
我这边报错,提示:”不适合在制定状态使用“
lingrain 2014-10-31
  • 打赏
  • 举报
回复
多谢,这个可以使用。 1、直接下载DLL:http://www.bouncycastle.org/csharp/download/bccrypto-net-1.7-bin.zip 2、添加引用。 3、命名空间,如: using Org.BouncyCastle; using Org.BouncyCastle.Crypto; using Org.BouncyCastle.Math; using Org.BouncyCastle.Crypto.Parameters;
引用 1 楼 github_22161131 的回复:
需要依赖一个第三方库,叫BouncyCastlenuget链接) xml转pem:

var rsa = new RSACryptoServiceProvider();
using(var sr = new StreamReader("e:\\key.xml"))
{
    rsa.FromXmlString(sr.ReadToEnd());
}
var p = rsa.ExportParameters(true);

var key = new RsaPrivateCrtKeyParameters(
    new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent), new BigInteger(1, p.D),
    new BigInteger(1, p.P), new BigInteger(1, p.Q), new BigInteger(1, p.DP), new BigInteger(1, p.DQ), 
    new BigInteger(1, p.InverseQ));

using (var sw = new StreamWriter("e:\\key.pem"))
{
    var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(sw);
    pemWriter.WriteObject(key);
}
pem转xml:

AsymmetricCipherKeyPair keyPair;
using(var sr = new StreamReader("e:\\key.pem"))
{
    var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(sr);
    keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
}
var key = (RsaPrivateCrtKeyParameters)keyPair.Private;
var p = new RSAParameters {
    Modulus = key.Modulus.ToByteArrayUnsigned(),
    Exponent = key.PublicExponent.ToByteArrayUnsigned(),
    D = key.Exponent.ToByteArrayUnsigned(),
    P = key.P.ToByteArrayUnsigned(),
    Q = key.Q.ToByteArrayUnsigned(),
    DP = key.DP.ToByteArrayUnsigned(),
    DQ = key.DQ.ToByteArrayUnsigned(),
    InverseQ = key.QInv.ToByteArrayUnsigned(),
};
var rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(p);
using (var sw = new StreamWriter("e:\\key.xml"))
{
    sw.Write(rsa.ToXmlString(true));
}
引用 1 楼 github_22161131 的回复:
需要依赖一个第三方库,叫BouncyCastlenuget链接) xml转pem:

var rsa = new RSACryptoServiceProvider();
using(var sr = new StreamReader("e:\\key.xml"))
{
    rsa.FromXmlString(sr.ReadToEnd());
}
var p = rsa.ExportParameters(true);

var key = new RsaPrivateCrtKeyParameters(
    new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent), new BigInteger(1, p.D),
    new BigInteger(1, p.P), new BigInteger(1, p.Q), new BigInteger(1, p.DP), new BigInteger(1, p.DQ), 
    new BigInteger(1, p.InverseQ));

using (var sw = new StreamWriter("e:\\key.pem"))
{
    var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(sw);
    pemWriter.WriteObject(key);
}
pem转xml:

AsymmetricCipherKeyPair keyPair;
using(var sr = new StreamReader("e:\\key.pem"))
{
    var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(sr);
    keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
}
var key = (RsaPrivateCrtKeyParameters)keyPair.Private;
var p = new RSAParameters {
    Modulus = key.Modulus.ToByteArrayUnsigned(),
    Exponent = key.PublicExponent.ToByteArrayUnsigned(),
    D = key.Exponent.ToByteArrayUnsigned(),
    P = key.P.ToByteArrayUnsigned(),
    Q = key.Q.ToByteArrayUnsigned(),
    DP = key.DP.ToByteArrayUnsigned(),
    DQ = key.DQ.ToByteArrayUnsigned(),
    InverseQ = key.QInv.ToByteArrayUnsigned(),
};
var rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(p);
using (var sw = new StreamWriter("e:\\key.xml"))
{
    sw.Write(rsa.ToXmlString(true));
}
winnowc 2014-10-25
  • 打赏
  • 举报
回复
需要依赖一个第三方库,叫BouncyCastlenuget链接) xml转pem:

var rsa = new RSACryptoServiceProvider();
using(var sr = new StreamReader("e:\\key.xml"))
{
    rsa.FromXmlString(sr.ReadToEnd());
}
var p = rsa.ExportParameters(true);

var key = new RsaPrivateCrtKeyParameters(
    new BigInteger(1, p.Modulus), new BigInteger(1, p.Exponent), new BigInteger(1, p.D),
    new BigInteger(1, p.P), new BigInteger(1, p.Q), new BigInteger(1, p.DP), new BigInteger(1, p.DQ), 
    new BigInteger(1, p.InverseQ));

using (var sw = new StreamWriter("e:\\key.pem"))
{
    var pemWriter = new Org.BouncyCastle.OpenSsl.PemWriter(sw);
    pemWriter.WriteObject(key);
}
pem转xml:

AsymmetricCipherKeyPair keyPair;
using(var sr = new StreamReader("e:\\key.pem"))
{
    var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(sr);
    keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject();
}
var key = (RsaPrivateCrtKeyParameters)keyPair.Private;
var p = new RSAParameters {
    Modulus = key.Modulus.ToByteArrayUnsigned(),
    Exponent = key.PublicExponent.ToByteArrayUnsigned(),
    D = key.Exponent.ToByteArrayUnsigned(),
    P = key.P.ToByteArrayUnsigned(),
    Q = key.Q.ToByteArrayUnsigned(),
    DP = key.DP.ToByteArrayUnsigned(),
    DQ = key.DQ.ToByteArrayUnsigned(),
    InverseQ = key.QInv.ToByteArrayUnsigned(),
};
var rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(p);
using (var sw = new StreamWriter("e:\\key.xml"))
{
    sw.Write(rsa.ToXmlString(true));
}

110,533

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧