为 jsencrypt 增加私钥加密公钥解密的方法逻辑
首先声明,使用 RSA 非对称加密,正常的使用情景是公钥加密、私钥解密。
因为正常使用情景下,公钥是公开的,如果将私钥加密的数据发出去,使用公钥解密,其实理论上并没有起到加密的作用。
私钥加密、公钥解密的使用场景是在于防篡改,确定私钥发来的数据是正确的。
其实某种程度来说,确实就没必要再实现私钥加密,公钥解密的逻辑了。
不过出于强迫症的角度,理论上私钥是可以用于加密的,公钥也可以用于解密,那为什么不实现一下呢。。。
在 .NET 中,使用 BouncyCastle 是可以轻易实现的,但在 JavaScript 中,几乎所有 RSA 的算法库都没有进行支持。
好在有这种奇奇怪怪的需求的人们不少,jsencrypt 也算是使用比较广泛的一个 JavaScript 中的 RSA 算法库了,
总结了一下网上大家的思路,基于 jsencrypt 已有的公钥加密、私钥解密逻辑,修改了一套私钥加密、公钥解密的逻辑出来。
这里面比较核心的点,是 PKCS #1: RSA Encryption Version 1.5 的数据块组成
本身在 jsencrypt 中,私钥公钥的算法都是通用的,只是基于 pkcs 的封装有一些差异,导致无法使用私钥加密、公钥解密。
在此记录一下,
在需要加密时,在进行 RSA 运算前,需要先将源数据 D 封装为 Encryption block(EB)。
其中 PKCS #1: RSA Encryption Version 1.5 的数据块组成如下:
EB = 0x00 + BT + PS + 0x00 + D
说明:EB 为转化后的字节数组(一般以 16 进制表示),EB字节数组长度 = 密钥长度 / 8
0x00:第一位固定为 0x00
BT:公钥加密:0x02,私钥加密:0x00 或 0x01
PS:填充位,除固定位和数据位外,对 EB 的其余字节位进行填充,一般至少保留 8 位。
BT = 0x00 时全部填充 0x00(此种情景下,数据部分的首位字节必须非零,否则将无法准确的识别数据区)
BT = 0x01 时全部填充 0xFF
BT = 0x02 时随机产生数字填充(不允许填充 0x00)
0x00:源数据 D 的前一个字节,固定为 0x00,用于分隔填充位与数据区
D:源数据,填充在 EB 最后,因以上组成部分,源数据字节数组最大长度 = 密钥长度 / 8 - (1 + 1 + 8 + 1),即:EB长度-11
一般 RSA 密钥长度为 1024 位,则:
EB字节数组长度 = 1024 / 8 = 128
源数据字节数组最大长度 = 128 - 11 = 117
同理,解密就是在 RSA 运算后,按以上结构将数据再进行取出即可。
参考文章:
https://www.cnblogs.com/wsss/p/11516318.html
https://datatracker.ietf.org/doc/html/rfc2313#section-8.1
https://github.com/lwenhaoCN/RSA
https://blog.csdn.net/junxuezheng/article/details/109824552
因为看 jsencrypt 项目已经很久不怎么更新了,感觉也不太会有大更新了,直接 fork 了一个进行修改,后续可以直接用了。
修改好的 jsencrypt 项目地址:https://github.com/xwgli/jsencrypt
输了你,赢了世界又如何...
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!
2023-05-09 如何修改 docker 默认网段(bridge、docker0 的网段)
2022-05-09 记录几个图标下载、LOGO、Favicon 生成网站
2022-05-09 记录如何在 docker 中部署运行 openwrt 系统