【问题标题】:Read DER private key in C# using BouncyCastle使用 BouncyCastle 在 C# 中读取 DER 私钥
【发布时间】:2013-12-14 16:26:18
【问题描述】:

我正在尝试使用 BouncyCastle 将 RSA 私钥读入 .Net 以测试我之前加密的数据。使用公钥和 Bouncy Castle 加密数据工作正常,我还使用与下面相同的私钥(DER 格式)在 PHP 应用程序中成功解密我的数据,但我不知道为什么我不能在 .Net 中创建私钥来做同样的事情:

byte[] privatekey = File.ReadAllBytes(@"C:\Users\Luke\privkey.der");
var rsaKeyParameters = (RsaKeyParameters)PrivateKeyFactory.CreateKey(privatekey);

第二行抛出异常:

“工厂中的未知对象:DerInteger\r\n参数名称:obj”

我也尝试使用流而不是字节数组,并且发生了同样的错误。密钥对是使用 OpenSSL 创建的,如前所述,使用 openssl_private_decrypt() 和 .Net 代码中的相同密钥在 PHP 中进行解密。我还尝试了相同密钥的 PEM 格式,但也没有用(但我认为 BC 不直接支持 PEM)

以前有人做过吗?谢谢

【问题讨论】:

  • 你能给我们看看 DER 格式吗?如果它是文本文件,那么它不是 DER,而是 DER 的 PEM 编码。在这种情况下,您首先需要移除 ASCII 装甲(也称为 PEM)。
  • 它是二进制格式,所以它显然不会粘贴到这里。我使用了一个在线 javascript 检查器,它对密钥感到满意并显示了所有内容。
  • 我了解 Lukos,但是如果我们不知道私钥的格式,那么我们就看不到哪里出了问题,除非我们自己遇到了这个问题(或者可能通过查看源代码) .如果此论坛不起作用,您可能想试试 Bouncy Castle 邮件列表...
  • 我不确定您在问什么,因为我无法将文件的二进制文件粘贴到文本编辑器中。它是使用 openssl genrsa -out privkey.der -outform der 2048 生成的。在 PHP 中工作的解密然后将 der 密钥转换为 pem,也使用 openssl。

标签: c# encryption bouncycastle


【解决方案1】:

问题是我假设 PublicKeyFactory 和 PrivateKeyFactory 是免费的,因为它们在同一个命名空间中。他们不是!

要解码私钥,我需要以下替代代码:

var privKeyObj = Asn1Object.FromStream(privatekey);
var privStruct = new RsaPrivateKeyStructure((Asn1Sequence)privKeyObj);

// Conversion from BouncyCastle to .Net framework types
var rsaParameters = new RSAParameters();
rsaParameters.Modulus = privStruct.Modulus.ToByteArrayUnsigned();
rsaParameters.Exponent = privStruct.PublicExponent.ToByteArrayUnsigned();
rsaParameters.D = privStruct.PrivateExponent.ToByteArrayUnsigned();
rsaParameters.P = privStruct.Prime1.ToByteArrayUnsigned();
rsaParameters.Q = privStruct.Prime2.ToByteArrayUnsigned();
rsaParameters.DP = privStruct.Exponent1.ToByteArrayUnsigned();
rsaParameters.DQ = privStruct.Exponent2.ToByteArrayUnsigned();
rsaParameters.InverseQ = privStruct.Coefficient.ToByteArrayUnsigned();
var rsa = new RSACryptoServiceProvider();
rsa.ImportParameters(rsaParameters);
return Encoding.UTF8.GetString(rsa.Decrypt(Convert.FromBase64String(ciphertext), true));

非常感谢 owlstead 的帮助。

【讨论】:

  • PrivateKeyFactory 与格式为 ASN.1 PrivateKeyInfo 的密钥一起使用,这基本上意味着有一些标题可以自我描述其中的密钥类型。正如您所发现的那样,RSA 私钥通常在没有这个的情况下直接存储为 RsaPrivateKeyStructure。仅供参考,我在 BC 的 DotNetUtilities 类中添加了新的实用程序方法,用于从 RsaPrivateKeyStructure 转换为 RSAParameters 和 RSA(CryptoServiceProvider)。
  • 以防万一有人遇到与我相同的问题,我在ImportParameters 电话中收到了Bad Data 异常(非常有帮助)。我注意到 DP 只有 63 个字节,而其他的是 64128。我在DPstart 中添加了一个零字节,一切正常。
猜你喜欢
  • 2018-09-30
  • 2011-07-31
  • 2014-05-20
  • 2012-01-17
  • 1970-01-01
  • 2015-03-21
  • 2017-12-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多