[C#] jsencrypt RSA加密后 后台解密概率性失败 (The length of the data to decrypt is not valid for the size of thi)

2 篇文章 0 订阅
2 篇文章 0 订阅

异常场景:

前端使用:jsencrypt.js 进行RSA加密

后端使用C#(System.Security.Cryptography.Algorithms或System.Security.Cryptography.Csp)进行解密

出现小概率解密失败的情况

异常提示:

System.Security.Cryptography.CryptographicException: 資料錯誤。

System.Security.Cryptography.Algorithms:The length of the data to decrypt is not valid for the size of this key.

异常原因:

  版本:

jsencrypt 2.3.1 and 3.0.0-rc.1

  问题:

JSEncrypt#encrypt有时会生成长度小于模数的密文,即,密文不会填充模数长度的前导0x00值。

根据RFC 8017, Section-7.2.2, 第1步,长度小于模数的密文是无效的。

JSEncrypt#decrypt似乎考虑到了这一点,因为它还会解密太短的密文 正确地。 当以其他语言(例如,C#)执行解密时,会出现问题。

这里 解密会中止,并显示一条错误消息,密码长度不正确,请参见此SO发行的 jsencryptjs-encrypt-but-python-cannot-decrypt.

以上为 travist/jsencrypt项目的Issues相关的译文 原文点击这里

总得来说就是jsencrypt.js在生成密文时可能会生成小于规定长度的密文,jsencrypt.js能够正确解密这种密文,但一些后台语言如C#,Python等在解密是就会出现异常

解决方案:

解决这个问题之前需要了解一下 密文长度,在不考虑切片加密的情况下,密文长度和秘钥长度一致。

例如我们选用1024bit的秘钥那么密文长度就应该是128B(1024/8)。

这里的密文长度指的是是Byte数组的长度,不是Base64字符串的长度,因为Base64有补全机制

那么我们以1024bit的秘钥为例解决方案如下:

方案一:前端处理(JS)

在使用jsencrypt.js加密后对异常密文进行补全处理。代码如下:

var RSAPublicKey = '1024bit公钥';
var encrypt = new JSEncrypt();
encrypt.setPublicKey(RSAPublicKey);
var ciphertext=encrypt.encrypt(content);

//对密码尝试进行补全
ciphertext=btoa(atob(ciphertext).padStart(128, "\0"));

方案二:后端处理(C#)

在解密前对密文尝试进行补全处理。代码如下

/// <summary>
/// 补全密文
/// </summary>
/// <param name="strCiphertext">密文</param>
/// <param name="keySize">秘钥长度</param>
/// <returns>补全后的密文</returns>
private static string CorrectionCiphertext(string strCiphertext, int keySize = 1024)
{
    int ciphertextLength = keySize / 8;
    byte[] data = Convert.FromBase64String(strCiphertext);
    var newData = new List<byte>(data);
    while (newData.Count < ciphertextLength)
    {
        newData.Insert(0, 0x00);
    }
    return Convert.ToBase64String(newData.ToArray());
}

以上就是 RSA Decrypt 异常的解决方案!

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值