最近需要在前端实现一个功能,后端对数据使用RSA私钥加密后,前端使用公钥对数据进行解密,在前端项目中使用jsencrypt库进行实现,但是jsencrypt库在解密时不支持使用公钥解密,网上有一些教程是通过修改源代码的方式进行实现,在实际阅读源码之后发现不需要这么麻烦,可以直接在调用的时候做些调整。废话不多说,直接上代码。
import JSEncrypt from 'jsencrypt'
import { parseBigInt } from 'jsencrypt/lib/lib/jsbn/jsbn'
function pkcs1unpad2(d, n) {
var b = d.toByteArray()
var i = 0
while (i < b.length && b[i] === 0) {
++i
}
// if (b.length - i !== n - 1 || b[i] !== 2) {
// return null
// }
++i
while (b[i] !== 0) {
if (++i >= b.length) {
return null
}
}
var ret = ''
while (++i < b.length) {
var c = b[i] & 255
if (c < 128) { // utf-8 decode
ret += String.fromCharCode(c)
} else if ((c > 191) && (c < 224)) {
ret += String.fromCharCode(((c & 31) << 6) | (b[i + 1] & 63))
++i
} else {
ret += String.fromCharCode(((c & 15) << 12) | ((b[i + 1] & 63) << 6) | (b[i + 2] & 63))
i += 2
}
}
return ret
}
function decrypt(data, publicKey) {
const encrypt = new JSEncrypt()
encrypt.setPublicKey(publicKey)
// 不支持公钥解密
// 自定义解析方法支持公钥解析
const rsaKey = encrypt.getKey()
rsaKey.decrypt = function(ctext) {
var c = parseBigInt(ctext, 16)
var m = this.doPublic(c)
if (m == null) {
return null
}
return pkcs1unpad2(m, (this.n.bitLength() + 7) >> 3)
}
return encrypt.decrypt(data)
}
直接调用decrypt
方法即可实现公钥解密,如果想要全局生效的话,这里提供一个思路就是调整代码直接对RSAKey
的原型链方法进行修改。