问题描述
由于jsEncrypt.js代码里面含有window、document、navigator对象,这些对象可以在pc端的浏览器使用,但是小程序没有这些对象,所以直接在小程序引入jsEncrypt.js会直接报错,下面主要介绍如何在jsEncrypt.js里面对这些对象进行兼容。
jsEncrypt.js介绍
功能
一种RSA加密的解决方案。 这种加密模式被称为"非对称加密算法"。
(1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。
(2)甲方获取乙方的公钥,然后用它对信息加密。
(3)乙方得到加密后的信息,用私钥解密。
如果公钥加密的信息只有私钥解得开,那么只要私钥不泄漏,通信就是安全的。
使用场景
加密验证码。
// 实例化JSEncrypt对象。并设置公钥
var cryptFirst = new JSEncrypt();
cryptFirst.setPublicKey('-----BEGIN PUBLIC KEY----- MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALQCZoxawKSTyMTLEU5QlYNVIOBMafGq vVGp6bFv2gQ8Px5ZJVzIG1TjIUQo1IpGQBgC+JSJFaGLsv196dlcloUCAwEAAQ== -----END PUBLIC KEY-----');
// 实例化JSEncrypt对象。并设置私钥
var cryptSec = new JSEncrypt();
cryptSec.setPrivateKey('-----BEGIN PRIVATE KEY----- MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAtAJmjFrApJPIxMsR TlCVg1Ug4Exp8aq9UanpsW/aBDw/HlklXMgbVOMhRCjUikZAGAL4lIkVoYuy/X3p 2VyWhQIDAQABAkBwdoN9MwHikNZBZSGFzUDsEZZ9rCAQtXycdcykZ95NAA5Mlb0j 77FLUhON8XEa+YVORwYn2GoP+ZZxGib7OtYBAiEA4nJRIzFn2Yr6y36r1rI6GP28 lxEDe5z/wytqm+XFswUCIQDLgJis+LVfzLM0MLVzDyuEy2GoLY46+WnaW8J2PSet gQIhANykSLzC2g6VJbN8VJFYjdVl/wkvMbaTjn4r4q/OnejFAiBPatgqaMUfpdsp uviU9o6dPGHYKC8hhMRymuzBCAy8AQIhAJlTJgdsJD7cjDCvFOv5v2Xz1JQQp03I vGjIsmEbdbEp -----END PRIVATE KEY-----'); var text = 'secret';
// 使用公钥加密数据
var enc = cryptFirst.encrypt(text);
// 现在使用私钥解密数据
var dec = cryptSec.decrypt(enc);
console.log(dec === text); // true
开始兼容处理
源代码
在线预览:源代码地址
兼容window.crypto
源代码第2754行
if (window.crypto && window.crypto.getRandomValues) { // 生成长度为256,元素值为0的数组
var z = new Uint32Array(256); // 生成长度为256,元素随机值的数组
window.crypto.getRandomValues(z);
}
兼容代码
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);
兼容window.removeEventListener、window.detachEvent
源代码
if (window.removeEventListener) {
window.removeEventListener("mousemove", onMouseMoveListener_1, false);
} else if (
window.detachEvent) {
window.detachEvent("onmousemove", onMouseMoveListener_1);
}
兼容处理:
直接删掉,监听的事件不会影响到加密和解密
兼容navigator.appName、navigator.userAgent
源代码
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;
}
兼容处理:
直接删掉。navigator主要是对浏览器的判断
最后
去一个在线压缩js的网站压缩一下代码,然后在小程序里引入就搞定啦。
总结
兼容处理其实比较简单粗暴,主要学到了一些第三方库在小程序的兼容处理其实很简单,不用太过畏惧修改源码。
定义一个window就OK了,jsencrypt原来的代码不动
const window = { crypto:{ getRandomValues(array){ for (var i = 0, l = array.length; i < l; i++) { let r = Math.floor(Math.random() * 3)+8; array[i] = +Math.random().toFixed(r).split(".")[1] } return array; } } }
页面报这个错
还有问题啊
可以用这个:https://blog.csdn.net/u010059669/article/details/109067975
Cannot set property 'JSEncrypt' of undefined
它采用
window.JSEncrypt = JSEncrypt;
暴露JSEncrypt类。
这个window也是undefined的。
const jsencrypt = require('jsencrypt.js')
{
var sign = new jsencrypt.JSEncrypt();
}
不能全删,留一个if的执行片段
eval is not a function 报错了呢
jsEncrypt 支持吃RSA 1024的,RSA2048的可以找我
RSA加密demo:https://github.com/zhangs3721/wx_jsencrypt 使用了 jsencrypt.js & jsencrypt.min.js ,前后端都可用。
我改好了,就按上面说的操作即可。测试通过了。需要的话私信。
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;
}
不能全删,留一个if的执行片段
BigInteger.prototype.am = am3;
dbits = 28;
全部删掉的话就会是false