如何在C#中解析(转换为RSAParameters)X.509私钥?

时间:2017-05-22 06:34:14

标签: c# encryption rsa x509certificate private-key

我正在使用加密通道加密两台设备之间的通信。所以我创建了一个辅助类来进行加密和解密。我搜索了很多,发现了一段可以将RSA公钥解析为RSACryptoServiceProvider的代码。

这是代码:

public static RSACryptoServiceProvider DecodeX509PublicKey(byte[] x509key)
{
    byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };
    byte[] seq = new byte[15];
    MemoryStream mem = new MemoryStream(x509key);
    BinaryReader binr = new BinaryReader(mem);
    byte bt = 0;
    ushort twobytes = 0;

    try
    {

        twobytes = binr.ReadUInt16();
        if (twobytes == 0x8130)
            binr.ReadByte();
        else if (twobytes == 0x8230)
            binr.ReadInt16();
        else
            return null;

        seq = binr.ReadBytes(15);
        if (!CompareBytearrays(seq, SeqOID))
            return null;

        twobytes = binr.ReadUInt16();
        if (twobytes == 0x8103)
            binr.ReadByte();
        else if (twobytes == 0x8203)
            binr.ReadInt16();
        else
            return null;

        bt = binr.ReadByte();
        if (bt != 0x00)
            return null;

        twobytes = binr.ReadUInt16();
        if (twobytes == 0x8130)
            binr.ReadByte();
        else if (twobytes == 0x8230)
            binr.ReadInt16();
        else
            return null;

        twobytes = binr.ReadUInt16();
        byte lowbyte = 0x00;
        byte highbyte = 0x00;

        if (twobytes == 0x8102)
            lowbyte = binr.ReadByte();
        else if (twobytes == 0x8202)
        {
            highbyte = binr.ReadByte();
            lowbyte = binr.ReadByte();
        }
        else
            return null;
        byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };
        int modsize = BitConverter.ToInt32(modint, 0);

        byte firstbyte = binr.ReadByte();
        binr.BaseStream.Seek(-1, SeekOrigin.Current);

        if (firstbyte == 0x00)
        {
            binr.ReadByte();
            modsize -= 1;
        }

        byte[] modulus = binr.ReadBytes(modsize);

        if (binr.ReadByte() != 0x02)
            return null;
        int expbytes = (int)binr.ReadByte();
        byte[] exponent = binr.ReadBytes(expbytes);

        RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
        RSAParameters RSAKeyInfo = new RSAParameters();
        RSAKeyInfo.Modulus = modulus;
        RSAKeyInfo.Exponent = exponent;
        RSA.ImportParameters(RSAKeyInfo);
        return RSA;
    }
    catch (Exception)
    {
        return null;
    }

    finally { binr.Close(); }
}

使用公钥可以很棒。但我的问题是如何解析X.509私钥?我并不熟悉RSA密钥的结构。

密钥是从 node.js

中的node-rsa生成的

提前致谢。的其中p 3

1 个答案:

答案 0 :(得分:1)

您目前有一个有效的RSAPublicKey结构阅读器。该结构和RSAPrivateKey结构可以在(RFC 3447附录A.1)[https://tools.ietf.org/html/rfc3447#appendix-A]中找到。

.NET不支持“多元素”(超过2个)RSA(但也不支持其他任何人),因此您可以坚持使用版本0格式。字段名称应该从注释中的替代名称中清楚,但如果不清楚:

  • modulus - > Modulus
  • publicExponent - > Exponent
  • privateExponent - > D
  • prime1 - > P
  • prime2 - > Q
  • exponent1 - > DP
  • exponent2 - > DQ
  • coefficient - > InverseQ

您还需要添加(或删除)填充零(左侧)到值

  • D.Length == Modulus.Length
  • hm =(Modulus.Length + 1)/ 2 //半圈
  • P,Q,DP,DQ,InverseQ各自具有长度== hm。