当前位置:首页 » 《休闲阅读》 » 正文

前端使用JSEncrypt对登录密码进行RSA加密解密

5 人参与  2024年03月23日 10:30  分类 : 《休闲阅读》  评论

点击全文阅读


环境

Vue3、soybean admin: “1.0.0”(native-ui: “2.38.0”)、pnpm: “8.5.3”、jsencrypt: “3.3.2”

使用

后端那边要求使用RSA非对称性加密,查阅了网上的资料,CryptoJS并不支持RSA加密,所以选择JSEncrypt

1. 下载依赖

pnpm安装依赖JSEncrypt

pnmp install jsencrypt --save

2. 加密登录密码

后端会给出公钥,用于登录密码的加密,现在我们通过JSEncrypt进行RSA加密

加密密码的方法如下:

function getEncryptedPassword(value: string) {  const publicKey = ""  let encrypt = new JSEncrypt();  encrypt.setPublicKey(publicKey);  let encrypted = encrypt.encrypt(value);  return encrypted;}

3. 登录失败

输入密码:123456,点击登录,接口报错“用户名或密码不正确”。检查后发现,加密出来的字符串和API文档给的字符串不一样。

JSEncrypt加密

AiSCv0JWI47eEmwfCDdzH9jtHZZo/tREW3QO2JO54rNhHZ8YSOELUdWsMP4wfjKYxEZugXUujjK1xTUeejq/KWYbp9qlyInFA2xheNG4a3a+s6ER9NLrsT9LAvD6YP8JdF8EZDl/zCMlQ5Fdh6FqNKlOtIJuiGNhGoPe48y7N9I=

后端API文档示例

090558eddebdef1dd02fe0a8cd59524d5da249d19084333ab2cb050b66aca9f868145a090b643fd9087e7baf5c967c99104acafb4946e1ec5ed78e29957183e3e9955fd1b981728091435bde75da1f62f83202511a6dfbd625f9cf7942536422ad36f3e742804b6aa11aa27ce13ab4feb7b1d9ea7e2e8d3d876d9a685a2a18a9

一眼就不对劲,但是又不知道怎么能变成后端给出的那种编码。怀疑是JSEncrypt的问题。

尝试用后端给的私钥去解密:

function decryptPassword(encryptedPwd: string) {  const privateKey= ""  let decrypt = new JSEncrypt();  decrypt.setPublicKey(privateKey);  let password = decrypt.decrypt(encryptedPwd);  return password;}

解密出来确实也是123456,证明了RSA加密流程其实没有问题的,很神奇。

JSEncrypt文档给出的方法很少很少,不清楚如何转变成正确的编码。找了很多资料,最后发现了一个文章:Hutool配合jsencrypt进行RSA加解密,这个博主看了JSEncrypt源码,加密出来的字符串是Base64,而在解密的时候,会把传进来的Base64转成Hex,再去执行解密方法!

4. 解决问题

根据文章知道了,有种编码叫Hex,兴许后端给的就是Hex,直接用在线网站试了Base64转Hex,尝试了一下,果然就登录成功了!

重新整理加密代码,如下:

function getEncryptedPassword(value: string) {  const publicKey = ""  let encrypt = new JSEncrypt();  encrypt.setPublicKey(publicKey);  let encrypted = encrypt.encrypt(value);  // copy form stackoverflow  let base64ToHex = (base64: string) => {    var raw = atob(base64);    var hex = '';    for (var i = 0; i < raw.length; i++) {      var _hex = raw.charCodeAt(i).toString(16)      hex += (_hex.length == 2 ? _hex : '0' + _hex);    }    return hex;  }    // JSEncrypt转成base64了,后端需要的是Hex  const hexPassword = base64ToHex(encrypted.toString());  return hexPassword;}

5. 补充知识

对编码、加密解密不熟悉,导致一眼看不出问题,花了很多时间去排查。特别是一直以为Hex是哈希的意思,哈希跟加密也有点关联,一时间混淆了

科普一下

Hex,也就是十六进制,也称为Base16区分Base64:Base64使用一个包含64个字符的字符集,包括大写字母(A-Z)、小写字母(a-z)、数字(0-9)以及"+“和”/“符号。有时,Base64编码还会使用”="作为填充字符,以确保编码后的字符串长度是4的倍数。区分Base16:Base16(Hexadecimal)使用一个包含16个字符的字符集,包括数字(0-9)和字母(A-F)。Base16编码不使用"+“、”/“或”="字符。除了Base64、Base16,还有其它编码方式,比如Base32、Base58、ASCII编码、Unicode编码(UTF-8、UTF-16、UTF-32)、URL编码等等

资料来自文心一言,欢迎评论指出问题!


总结

对于这次RSA非对称加密登录密码对接的问题,有两点总结:

之前加密密码都是用的CryptoJS,直接用盐加密登录就能成功,从来没有想过编码方式的问题还有其实网上使用RSA去加密登录密码的不多,用MD5、AES的比较多,这也是花了一些时间排查的原因。

通过本次对接了解到了一些编码方面的知识,下次遇到应该不会那么懵了,希望能帮助到大家!


点击全文阅读


本文链接:http://zhangshiyu.com/post/84112.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1