小程序加密jsencrypt.js使用 Uncaught TypeError: Cannot read property ‘appName‘ of undefined 已解决

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);

操作到这就可以解决小程序中的问题,可以使用了


对jsencrypt.js 进行了优化, **对大于118位的密码进行加密**

加入下面代码在 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

你可能感兴趣的:(小程序,#,javaScript)