【问题标题】:Decrypting with private key from .pem file in c# with .NET crypto library使用 .NET 加密库在 c# 中使用 .pem 文件中的私钥解密
【发布时间】:2010-11-12 20:19:38
【问题描述】:

我知道这是与this one 类似的问题,但在我前往 Bouncey Castle 路线之前,有谁知道是否可以从 .pem 文件加载 RSA 密钥对,例如:

 -----BEGIN RSA PRIVATE KEY-----
 MIIBOgIBAAJBALKzy66nRuof8Fg0ItatyHS9RiDIKH0m5lorKzKn4y5wR6BXpVUv
 ZwnevrAJWBd6EPr/lcV3hjObxD6+q9vmN8ECAwEAAQJAGNcxWwfZrbXe3QPyS9FA
 aindU7U/G5aKssIJcTMxO0UYpGU+WArJbboKeEIE7bpNfhDOKTL7ZL6kWBR1Svlh
 WQIhAOhtx+xXuSrIot59tmXZaypBDjA4n+Xare0ObFLQxWuvAiEAxNMwm6w33bVr
 FHS9slkOh59Le2mgs0uNT6perHaRP48CIGMyRzrlDY/m5SvTtz6slgIIlceawxNU
 Sxp7J1wI4djdAiA6+BchHNjkCP2a9Fr9OydaRMSFpiDqduFQk/enbiKYSwIhANO3
 SQ51oLFtWN9gX3tfKTXflyO6BV8rgPo980d9CEsb
 -----END RSA PRIVATE KEY-----

直接使用 .NET 3.5 加密库而无需去第三方或自己动手?

【问题讨论】:

  • @CraigMcQueen 好问题...我认为是错误的。

标签: c# .net-3.5 rsacryptoserviceprovider


【解决方案1】:

http://www.jensign.com/opensslkey/index.html

来源http://www.jensign.com/opensslkey/opensslkey.cs 更新:此网址不再提供源代码。现在可以在https://gist.github.com/stormwild/7887264https://web.archive.org/web/20170731015547/http://www.jensign.com/opensslkey/opensslkey.cs 找到它。

编辑:摘录相关代码:

首先,提取 ---- BEGIN ---- 和 ---- END ---- 部分之间的文本,并将其 base64 解码为字节数组(有关详细信息,请参见上面的链接),然后传递它到:

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

【讨论】:

  • 我试一试...你是什么意思这是另一个问题的解决方案?我引用的问题的公认答案使用了 Bouncy Castle 库(顺便说一句,它也适用于我)。我只是想尽可能减少对 3rd 方库的依赖。即使是那些拥有非常慷慨的许可的人。
  • @Tim Jarvis:目前另一个问题的最佳答案是“你可以看看 JavaScience 的 OpenSSLKey 源代码”。这与我在上面链接和复制的内容相同。 (BouncyCastle 是提问者自己回答的方式,而不是接受的答案......)
  • 啊,当然。干杯。还没试过这个……准备去吃午饭了。会告诉你这件事的进展的。 (顺便说一下 +1 可能还有 +15)
  • 好吧,我不知道为什么这对另一个问题的海报不起作用,但它对我来说很好。 (有几个小模组。)
  • 为了继续使用密钥导出到 PFX,我必须设置一个 csp KeyContainerName。代替 new RSACryptoServiceProvder(),执行 new RSACryptoServiceProvider(new CspParameters() { KeyContainerName = Guid.NewGuid().ToString("B").ToUpper() });名称的内容可能根本不重要,但大写括号 GUID 是我在其他地方看到的,现在我可以 X509Certificate2.Export 并保留私钥。
【解决方案2】:

我创建了一个小型帮助程序 NuGet 包来创建基于公钥和私钥 (rsa) 的 X509 证书。

有关基于opensslkey 的功能和代码示例,请参阅NuGetGithub-project

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-17
    • 2011-04-18
    • 2018-11-25
    • 1970-01-01
    相关资源
    最近更新 更多