为什么在 C# 中加密时 RSA 解密在 node.js 中失败?
Why does RSA decryption fail in node.js when encrypted in C#?
我正在创建一个通过 node.js 服务器进行身份验证的 C# 应用程序。为此,我正在使用 RSA。我使用加密为服务器生成了 public 和私钥。每次客户端连接到服务器时,它都会为自己生成一个密钥对。客户端从端点获取服务器 public 密钥。我使用了 XML 字符串和 PEM 字符串,但它们都不起作用。 (使用 RSACryptoServiceProvider)当服务器试图解密它时,它抛出了一个 OAEP 解码错误。我正在尝试使用配对的私钥解密消息。
我查看了其他主题,但它们不是很有帮助。
这是服务器的代码。它 encrypts/decrypts 带有内置的加密模块。 (我已经用 node.js 客户端和 node.js 服务器测试了它,它可以工作。)
var encrypt = function(input, publicKey) {
var buffer = Buffer.from(input);
var encrypted = crypto.publicEncrypt(publicKey, buffer);
return encrypted.toString("base64");
};
var decrypt = function(input, privateKey) {
var buffer = Buffer.from(input, "base64");
var decrypted = crypto.privateDecrypt(privateKey, buffer);
return decrypted.toString("utf8");
};
module.exports = {
encrypt,
decrypt
}
编辑: 我制作了一个测试 C# 控制台应用程序,它接受一个输入字符串并使用我的 node.js 服务器的 public 密钥对其进行加密。
public const string pubKey = "<RSAKeyValue>public key etc etc</RSAKeyValue>";
private static void Main(string[] args)
{
string enc = encrypt(pubKey, args[0]);
Console.WriteLine(enc);
}
public static string encrypt(string publicKey, string decrypted)
{
RSACryptoServiceProvider csp = new RSACryptoServiceProvider();
csp.FromXmlString(publicKey);
byte[] bytesPlainTextData = Encoding.UTF8.GetBytes(decrypted);
byte[] bytesCipherText = csp.Encrypt(bytesPlainTextData, false);
string cipherText = Convert.ToBase64String(bytesCipherText);
return cipherText;
}
它给了我结果VnzRc4yhIa9XcSDvHyDkwCNHFG6Ps2dddyCD4RHE4jIqvMl56DhmIJWprLRZle9EpZ/3Zq4fDkkplHUGBidoH+9VkPV/2+sV6P+C+4u6yisV5zTarZfjcvsShwBp/9z4YfOE7kQZVRENhvflrRw6GutxtDz0lO4KhvdvQztm0u7JmUB9ynM7XFYXOKT391InBs2eqRh+JRfJzTfhFqn3Bt8K/kKNE1xkvQV0GK7U1qSpWOWfB+0hdwNkUEQpT26jU93bAcex1SVwfbj4PJQMH6Wxzx2s6u4fcOzf9ELEgel/Fuj5b0UKHHE48B/zBmnoDsS3twt/8TJb9jbCU8S3ES/hKwndkS809bSoJl6TkBXErlOLCDpay3AO23+NjPGwSl1JvnFUVgTqAABd/yAcsokjIgxkbRqAvhC/js5Oh3y9wJwc9Z7V1ImPGcifIWsEBuH/8lerJdYw7ABB/eUZosC+tQkzvjr4H9urupM0mk6Zd+92sJaG/COrwOAPkiiM6lJK9ealRrlPMEKv39aWVr+brlQzN8zyoT+a0oGsYSPt9B/P3CJhbkbHqw9e1u9TZ7q9Ba7x/oqeRBmpRfFrcjegGFQkYViYkd1bswNF3KumqhBCsw4VeTkYmRNCKrLZdZyJ5BLSfvc+PTPOzDPVgOZb1InacmIWOqkapRbeELc=
然后,我做了一个简单的console.log(decrypt(stringAbove, privateKey));
它仍然给我以下错误:
Error: error:04099079:rsa routines:RSA_padding_check_PKCS1_OAEP_mgf1:oaep decoding error
填充有多种类型,显然加密试图使用 PKCS1(我猜),解密默认为 OAEP。
在 crypto.privateDecrypt
中,您可以 set the padding 例如。 padding: crypto.constants.RSA_PKCS1_PADDING
它应该可以工作。
如果可能(应该如此),你应该在两端都使用 OAEP,在这种情况下,你的 Node 代码已经可以了,因为默认是 OAEP,C# 也应该设置为 OAEP。
编辑:我先把它弄混了,但关键是,你可以在两端设置填充类型,而且它们必须匹配。 :)
我正在创建一个通过 node.js 服务器进行身份验证的 C# 应用程序。为此,我正在使用 RSA。我使用加密为服务器生成了 public 和私钥。每次客户端连接到服务器时,它都会为自己生成一个密钥对。客户端从端点获取服务器 public 密钥。我使用了 XML 字符串和 PEM 字符串,但它们都不起作用。 (使用 RSACryptoServiceProvider)当服务器试图解密它时,它抛出了一个 OAEP 解码错误。我正在尝试使用配对的私钥解密消息。
我查看了其他主题,但它们不是很有帮助。
这是服务器的代码。它 encrypts/decrypts 带有内置的加密模块。 (我已经用 node.js 客户端和 node.js 服务器测试了它,它可以工作。)
var encrypt = function(input, publicKey) {
var buffer = Buffer.from(input);
var encrypted = crypto.publicEncrypt(publicKey, buffer);
return encrypted.toString("base64");
};
var decrypt = function(input, privateKey) {
var buffer = Buffer.from(input, "base64");
var decrypted = crypto.privateDecrypt(privateKey, buffer);
return decrypted.toString("utf8");
};
module.exports = {
encrypt,
decrypt
}
编辑: 我制作了一个测试 C# 控制台应用程序,它接受一个输入字符串并使用我的 node.js 服务器的 public 密钥对其进行加密。
public const string pubKey = "<RSAKeyValue>public key etc etc</RSAKeyValue>";
private static void Main(string[] args)
{
string enc = encrypt(pubKey, args[0]);
Console.WriteLine(enc);
}
public static string encrypt(string publicKey, string decrypted)
{
RSACryptoServiceProvider csp = new RSACryptoServiceProvider();
csp.FromXmlString(publicKey);
byte[] bytesPlainTextData = Encoding.UTF8.GetBytes(decrypted);
byte[] bytesCipherText = csp.Encrypt(bytesPlainTextData, false);
string cipherText = Convert.ToBase64String(bytesCipherText);
return cipherText;
}
它给了我结果VnzRc4yhIa9XcSDvHyDkwCNHFG6Ps2dddyCD4RHE4jIqvMl56DhmIJWprLRZle9EpZ/3Zq4fDkkplHUGBidoH+9VkPV/2+sV6P+C+4u6yisV5zTarZfjcvsShwBp/9z4YfOE7kQZVRENhvflrRw6GutxtDz0lO4KhvdvQztm0u7JmUB9ynM7XFYXOKT391InBs2eqRh+JRfJzTfhFqn3Bt8K/kKNE1xkvQV0GK7U1qSpWOWfB+0hdwNkUEQpT26jU93bAcex1SVwfbj4PJQMH6Wxzx2s6u4fcOzf9ELEgel/Fuj5b0UKHHE48B/zBmnoDsS3twt/8TJb9jbCU8S3ES/hKwndkS809bSoJl6TkBXErlOLCDpay3AO23+NjPGwSl1JvnFUVgTqAABd/yAcsokjIgxkbRqAvhC/js5Oh3y9wJwc9Z7V1ImPGcifIWsEBuH/8lerJdYw7ABB/eUZosC+tQkzvjr4H9urupM0mk6Zd+92sJaG/COrwOAPkiiM6lJK9ealRrlPMEKv39aWVr+brlQzN8zyoT+a0oGsYSPt9B/P3CJhbkbHqw9e1u9TZ7q9Ba7x/oqeRBmpRfFrcjegGFQkYViYkd1bswNF3KumqhBCsw4VeTkYmRNCKrLZdZyJ5BLSfvc+PTPOzDPVgOZb1InacmIWOqkapRbeELc=
然后,我做了一个简单的console.log(decrypt(stringAbove, privateKey));
它仍然给我以下错误:
Error: error:04099079:rsa routines:RSA_padding_check_PKCS1_OAEP_mgf1:oaep decoding error
填充有多种类型,显然加密试图使用 PKCS1(我猜),解密默认为 OAEP。
在 crypto.privateDecrypt
中,您可以 set the padding 例如。 padding: crypto.constants.RSA_PKCS1_PADDING
它应该可以工作。
如果可能(应该如此),你应该在两端都使用 OAEP,在这种情况下,你的 Node 代码已经可以了,因为默认是 OAEP,C# 也应该设置为 OAEP。
编辑:我先把它弄混了,但关键是,你可以在两端设置填充类型,而且它们必须匹配。 :)