【问题标题】:Why does RSA decryption fail in node.js when encrypted in C#?为什么在 C# 中加密时 node.js 中的 RSA 解密失败?
【发布时间】:2021-01-26 14:21:08
【问题描述】:

我正在创建一个通过 node.js 服务器进行身份验证的 C# 应用程序。我为此目的使用 RSA。我使用加密为服务器生成了一个公钥和私钥。每次客户端连接到服务器时,它都会为自己生成一个密钥对。客户端从端点获取服务器公钥。我使用过 XML 字符串和 PEM 字符串,但它们都不起作用。 (使用 RSACryptoServiceProvider)当服务器试图解密它时,它抛出了一个 OAEP 解码错误。我正在尝试使用配对的私钥解密消息。

我查看了其他线程,但它们不是很有帮助。

这是服务器的代码。它使用内置的加密模块加密/解密。 (我已经使用 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 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

【问题讨论】:

    标签: c# node.js security encryption cryptography


    【解决方案1】:

    有多种填充类型,显然加密是尝试使用PKCS1(我猜),解密默认为OAEP。

    crypto.privateDecrypt 你可以set the padding 到例如。 padding: crypto.constants.RSA_PKCS1_PADDING 它应该可以工作。

    如果可能,您应该在两端都使用 OAEP(而且应该如此),在这种情况下,您的 Node 代码已经可以,因为默认为 OAEP,并且 C# 也应该设置为 OAEP。

    编辑:我先把它弄混了,但重点是,您可以在任一端设置填充类型,并且它们必须匹配。 :)

    【讨论】:

    • 谢谢。我将其更改为 OAEP,代码现在可以正常工作。 :)
    • 这是跨不同系统进行加密时的一般规则。您不能依赖默认值,因为不同的系统有不同的默认值。您需要明确设置所有内容,以便您知道两边都是相同的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-21
    • 1970-01-01
    • 2015-02-27
    • 1970-01-01
    • 1970-01-01
    • 2011-08-27
    • 2015-03-16
    相关资源
    最近更新 更多