网上很多帖子都有解决小程序使用jsencrypt rsa加密的方法,需要注意的是对版本有要求,新版本添加很多依赖,无法修改,目前我使用的是3.0.0-rc.1
npm i jsencrypt@3.0.0-rc.1
需要注意的是,在详情里面小程序最新版已经没有 使用npm模块 默认 1、npm init 2、npm i jsencrypt@3.0.0-rc.1 3、小程序构建npm 就可以使用,可以省略此步骤
小程序里没有window对象,具体需要修改源码,添加在最上面
var navigator = {
appName: 'Netscape',
userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1'
};
var window = {
ASN1: null,
Base64: null,
Hex: null,
crypto: null,
href: null
}
后续仍需修改源码,满足公钥解密
1、修改 RSAKey.prototype.decrypt 中 this.doPrivate 为 this.doPublic;
RSAKey.prototype.decrypt = function (ctext) {
var c = parseBigInt(ctext, 16);
var m = this.doPublic(c);
//var m = this.doPrivate(c);
if (m == null) {
return null;
}
return pkcs1unpad2(m, (this.n.bitLength() + 7) >> 3);
};
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;
}
var verify = new JSEncrypt();
var publicKey = `-----BEGIN PUBLIC KEY----- 公钥 -----END PUBLIC KEY-----`
verify.setPublicKey(publicKey);
// 使用私钥加密后的数据
var verified = verify.decrypt("Y/f5VqHyS6+9uVZIQLRFbLtNNvnYnrEOFRMCg0FmeojihSILNyrIerh5zYoVbRm9S16K65shz1VW5s/qQxk4hDmQ/cDo3yNdGhzS62XWN9f6rNIRk4pANSqrlt+3/kgooGlPcVRWGuNM2wX2WOJw0OgelZfFIbu0dIHlP8ohZ7w=");
console.log('解密后数据:', verified);