jsencrypt源码:jsencrypt.js
小程序中需要对传参到后台的数据进行加密,使用 jsencrypt.js 进行加密,由于 jsencrypt.js 对浏览器做了兼容,会再小程序中报错,所以需要修改 jsencrypt.js ,做兼容处理。
打包下载修改后的jsencrypt.js
一、navigator.appName
我使用的时候首先会报下面的错
Uncaught TypeError: Cannot read property 'appName' of undefined
源码
if (j_lm && (navigator.appName == "Microsoft Internet Explorer")) {
BigInteger.prototype.am = am2;
dbits = 30;
}
else if (j_lm && (navigator.appName != "Netscape")) {
BigInteger.prototype.am = am1;
dbits = 26;
}
else { // Mozilla/Netscape seems to prefer am3
BigInteger.prototype.am = am3;
dbits = 28;
}
解决方法:
可以保留最后else中的,其余删掉
navigator主要是对浏览器的判断,小程序中会报错
BigInteger.prototype.am = am3;
dbits = 28;
二、window.removeEventListener、window.detachEvent
源码:
if (window.removeEventListener) {
window.removeEventListener("mousemove", onMouseMoveListener_1, false);
}
else if (window.detachEvent) {
window.detachEvent("onmousemove", onMouseMoveListener_1);
}
解决方法:
直接删掉,监听的事件不会影响到加密和解密
三、window.crypto
if (window.crypto && window.crypto.getRandomValues) {
// Extract entropy (2048 bits) from RNG if available
var z = new Uint32Array(256);
window.crypto.getRandomValues(z);
for (t = 0; t < z.length; ++t) {
rng_pool[rng_pptr++] = z[t] & 255;
}
}
解决方法:
代码作用:// 生成长度为256,元素随机值的数组
删掉,加上下面代码
var getRandomValues = function (array) {
for (var i = 0, l = array.length; i < l; i++) {
array[i] = Math.floor(Math.random() * 256);
} return array;
}
var z = new Uint32Array(256);
getRandomValues(z);
操作到这就可以解决小程序中的问题,可以使用了
加入下面代码在 var JSEncrypt 代码块中
JSEncrypt.prototype.encryptLong = function(string) {
var k = this.getKey();
try {
var lt = "";
var ct = "";
//RSA每次加密117bytes,需要辅助方法判断字符串截取位置
//1.获取字符串截取点
var bytes = new Array();
bytes.push(0);
var byteNo = 0;
var len,c;
len = string.length;
var temp = 0;
for(var i = 0; i < len; i++){
c = string.charCodeAt(i);
if(c >= 0x010000 && c <= 0x10FFFF){
byteNo += 4;
}else if(c >= 0x000800 && c <= 0x00FFFF){
byteNo += 3;
}else if(c >= 0x000080 && c <= 0x0007FF){
byteNo += 2;
}else{
byteNo += 1;
}
if((byteNo % 117) >= 114 || (byteNo % 117) == 0){
if(byteNo-temp >= 114){
bytes.push(i);
temp = byteNo;
}
}
}
//2.截取字符串并分段加密
if(bytes.length > 1){
for(var i=0;i< bytes.length-1; i++){
var str;
if(i == 0){
str = string.substring(0,bytes[i+1]+1);
}else{
str = string.substring(bytes[i]+1,bytes[i+1]+1);
}
var t1 = k.encrypt(str);
ct += t1;
};
if(bytes[bytes.length-1] != string.length-1){
var lastStr = string.substring(bytes[bytes.length-1]+1);
ct += k.encrypt(lastStr);
}
return hex2b64(ct);
}
var t = k.encrypt(string);
var y = hex2b64(t);
return y;
} catch (ex) {
return false;
}
};
底部 exports 前加代码:key自己获取,简短展示
var rsaEncryptWithString = function(acceptString){
// 从后台获取公钥,这里省略,直接赋值
let publicKey = 'MIICdgIBADANBgkqhkiG9w0BAQEFKCaeVVNU6fM3'
let encryptor = new JSEncrypt() // 新建JSEncrypt对象
encryptor.setPublicKey(publicKey) // 设置公钥
// let rsaString = encryptor.encrypt(acceptString) // 对小于118位的密码进行加密
// 分段加密方法
let rsaString = encryptor.encryptLong(acceptString) // 对大于118位的密码进行加密
return rsaString
}
exports方法修改:
exports.JSEncrypt = JSEncrypt;
exports.rsaEncryptWithString = rsaEncryptWithString;
exports.default = rsaEncryptWithString;
使用方法:
import rsaEncryptWithString from 'jsencrypt.js'
let str = 'abcd
let data= encodeURIComponent(rsaEncryptWithString( JSON.stringify({str})))
// post 传参的 data 值
data: data
参考网站:微信社区-在小程序使用jsEncrypt.js