使用在 C# 中收到的 pem 或 pkcs 密钥解密字符串

Decrypt string using the pem or pkcs key received in c#

给定 pem 格式的密钥类似于

-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,DE1BB301BDE4BB45

msUEpZKZ0uaOmhGXBPnh2GoNSXyExdeqETd9w71l0G1bk1cCbiV4EOnmR7bcN+OE
(20 lines)
YoIx/E+tFHkt3gQcFhVUNgSOe/5+huXwRwUC5dthPzzZFlDCXHfwfrrBzOSGxZpX
uBs1JxY4qOLRdZVaZlQespForxBTYD6RuHi1UI5lqEW7363VyCLho9QYgGFM0LUi
qbln5WV37PTmayxMfzlGUB2XazwON+WU3obbXuCFXAy96Y6VGzv0lQ==
-----END RSA PRIVATE KEY-----

和加密字符串(使用public密钥加密)我尝试用下面的代码解密

TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider();
des.IV = HextoByte("DE1BB301BDE4BB45");                
des.Padding = PaddingMode.None;
des.Mode = CipherMode.CBC;   
des.Key = Convert.FromBase64String(//Key from above from ms.. to ==);                                                                  
byte[] encrypted = Convert.FromBase64String("");
byte[] decrypted = des.CreateDecryptor().TransformFinalBlock(encrypt, 0, encrypt.Length);
string decryptedString = Encoding.UTF8.GetString(decrypted) 

分配密钥时导致异常 "Specified key is not a valid size for this algorithm"

密钥是使用(也尝试使用 192)生成的

openssl genrsa -des3 -out Key.pem 2048

Public 密钥是使用

生成的
openssl rsa -in Key.pem -pubout > Key.pub

谁能帮我指出我遗漏或做错了什么?

谢谢

C# 中 3DES 密钥的最大大小为 192 位。另请参阅 MSDN 文档 here

因此您需要确保 Convert.FromBase64String() 确实 returns 24 字节。

另请查看以下问题/答案:

  • Why the TripleDES.Create().Key is not a valid size for this algorithm?
  • 3DES Key Size Matter in C#.Net

您正在使用带有 3DES 密码的 RSA 密钥。这是错误的密钥。

你问题中的私钥已经用3DES加密,可能使用基于密码的加密。您需要密钥才能解密私钥,然后才能将其用于任何用途。

一旦您恢复了 RSA 私钥,您很可能会用它来解密对称密钥。通常,每条加密消息都包含一个对称密码密钥,用收件人的 public 密钥加密。这就是您将使用恢复的 RSA 私钥解密的内容。

获得第二个对称密钥后,您可以使用它来解密实际消息,如您在问题中所示。

在伪代码中:

rsaPvtKey = passwordDecrypt(password, encryptedPrivateKey)
contentKey = rsaDecrypt(rsaPvtKey, encryptedContentKey)
message = tripleDesDecrypt(contentKey, encryptedMessage)

原问题中的代码非常接近。问题是密钥是从密码中推导出来的,消息是base-64编码的信息。成功解密后将生成 PKCS #8 格式的 RSA 私钥,.NET 应该有一个 API 用于加载它。

OpenSSL 密钥派生不是标准的(而且不是很好)。您需要查找或编写一些代码,以使用 MD5 哈希算法从您的密码创建 DES-EDE3 密钥。

d0 = md5(password || iv)        /* Hash password and IV */
d1 = md5(d0 || password || iv)  /* Hash first hash, password, and IV */
key = subarray(d0 || d1, 0, 24) /* Take the first 24 bytes of d0 + d1 */

JavaScience code 包含一个函数,GetOpenSSL3deskey 来执行此密钥派生。您可以使用提取的 iv、密码、1 的 count 和 2 的 miter 来调用它。

执行此操作后,将其分配给原始代码中的 des.Key。分配给 des.Key 的内容应该分配给 encrypt。 (这就是 DecodeOpenSSLPrivateKey 函数的作用。)当您完成解密时,字节数组 decrypted 将包含 PKCS #1 的中国剩余定理格式的 RSA 私钥。应该有一些 .NET API 可以从中构造一个 RSA 私钥。 (参见 DecodeRSAPrivateKey 函数。)

此 RSA 私钥随后可用于解密其他消息。