收藏
评论

在小程序使用jsEncrypt.js

问题描述

由于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的网站压缩一下代码,然后在小程序里引入就搞定啦。

总结

兼容处理其实比较简单粗暴,主要学到了一些第三方库在小程序的兼容处理其实很简单,不用太过畏惧修改源码。


最后一次编辑于  2018-11-21
收藏

16 个评论

  • Jason 、yang
    Jason 、yang
    2020-04-10

    还有问题啊

    2020-04-10
    赞同 2
    回复
  • 浅⃰雨⃰落⃰
    浅⃰雨⃰落⃰
    04-22

    定义一个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;
            }
        }
    }
    
    04-22
    赞同 1
    回复
  • 泰の隆
    泰の隆
    2020-03-31

    Cannot set property 'JSEncrypt' of undefined

    2020-03-31
    赞同 1
    回复 1
    • Jason 、yang
      Jason 、yang
      2020-04-10
      解决了吗
      2020-04-10
      回复
  • 杨工
    杨工
    2019-12-01

    它采用

    window.JSEncrypt = JSEncrypt;

    暴露JSEncrypt类。

    这个window也是undefined的。

    2019-12-01
    赞同 1
    回复 1
    • 杨工
      杨工
      2019-12-01
      解决办法是把它也删掉,用的时候
      2019-12-01
      1
      回复
  • _w
    _w
    2019-06-12
    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;
    }

    不能全删,留一个if的执行片段

     BigInteger.prototype.am = am3;
      dbits = 28;


    2019-06-12
    赞同 1
    回复
  • 小王子
    小王子
    03-17

    可以用这个:https://blog.csdn.net/u010059669/article/details/109067975

    03-17
    赞同
    回复
  • ꯭大꯭空꯭毅꯭
    ꯭大꯭空꯭毅꯭
    2020-08-19

    jsEncrypt 支持吃RSA 1024的,RSA2048的可以找我

    2020-08-19
    赞同
    回复
  • 喜大普奔
    喜大普奔
    2020-04-23

    RSA加密demo:https://github.com/zhangs3721/wx_jsencrypt 使用了 jsencrypt.js & jsencrypt.min.js ,前后端都可用。

    2020-04-23
    赞同
    回复
  • 黄飞林
    黄飞林
    2020-02-24

    我改好了,就按上面说的操作即可。测试通过了。需要的话私信。

    2020-02-24
    赞同
    回复 2
    • 冰雪融
      冰雪融
      2020-03-28
      你好,我的 encrypt返回false怎么办?
      2020-03-28
      回复
    • 有所谓丶
      有所谓丶
      04-09回复冰雪融
      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;
      }
      不能全删,留一个if的执行片段
       BigInteger.prototype.am = am3;
        dbits = 28;


      全部删掉的话就会是false
      04-09
      回复
  • 芒果入侵
    芒果入侵
    2020-02-20

    亲测可用,谢谢楼主提供的方法,解了燃眉之急

    2020-02-20
    赞同
    回复

正在加载...

登录 后发表内容