|
|
@@ -0,0 +1,344 @@
|
|
|
+import { hmacSha256 } from "./encrypt/hmacSha256"
|
|
|
+import * as CryptoJS from "./encrypt/aes.js"
|
|
|
+
|
|
|
+/**
|
|
|
+ * 工具类
|
|
|
+ */
|
|
|
+export class EncryptUtil {
|
|
|
+
|
|
|
+ // 随机生成32位字符串
|
|
|
+ static randomString(len = 32) {
|
|
|
+ let $chars =
|
|
|
+ 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'
|
|
|
+ let maxPos = $chars.length
|
|
|
+ let pwd = ''
|
|
|
+ for (let i = 0; i < len; i++) {
|
|
|
+ pwd += $chars.charAt(Math.floor(Math.random() * maxPos))
|
|
|
+ }
|
|
|
+ return pwd
|
|
|
+ }
|
|
|
+
|
|
|
+ //说明:
|
|
|
+ // 1.如果加密解密涉及到前端和后端,则这里的key要保持和后端的key一致
|
|
|
+ // 2.AES的算法模式有好几种(ECB,CBC,CFB,OFB),所以也要和后端保持一致
|
|
|
+ // 3.AES的补码方式有两种(PKS5,PKS7),所以也要和后端保持一致
|
|
|
+ // 4.AES的密钥长度有三种(128,192,256,默认是128),所以也要和后端保持一致
|
|
|
+ // 5.AES的加密结果编码方式有两种(base64和十六进制),具体怎么选择由自己定,但是加密和解密的编码方式要统一
|
|
|
+ //十六位十六进制数作为秘钥
|
|
|
+ // private static key = fun_aes.CryptoJS.enc.Utf8.parse("3454345434543454");
|
|
|
+ //十六位十六进制数作为秘钥偏移量
|
|
|
+ // private static iv = fun_aes.CryptoJS.enc.Utf8.parse('6666666666666666');
|
|
|
+
|
|
|
+ /**aes加密
|
|
|
+ * @param state true 存包长 false /r/n
|
|
|
+ */
|
|
|
+ static Encrypt(word, tkey, appid, state = true) {
|
|
|
+ let tiv = tkey.substr(0, 16)
|
|
|
+
|
|
|
+ // n = Base64.Instance.encode(n)
|
|
|
+ //明文拼接
|
|
|
+ let newStr = ''
|
|
|
+ if (state) {
|
|
|
+ // let n = this.pack(word.length)
|
|
|
+ // newStr = tiv + n + word + appid
|
|
|
+ newStr = tiv + word + appid
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ newStr = tiv + word + '\r\n' + appid
|
|
|
+ }
|
|
|
+
|
|
|
+ //加密后
|
|
|
+ let key = CryptoJS.enc.Utf8.parse(tkey);
|
|
|
+ let iv = CryptoJS.enc.Utf8.parse(tiv);
|
|
|
+
|
|
|
+ newStr = CryptoJS.enc.Utf8.parse(newStr);
|
|
|
+ var encrypted = CryptoJS.AES.encrypt(newStr, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
|
|
|
+ encrypted = encrypted.toString()
|
|
|
+ let mac = hmacSha256.Instance.hex_hmac_sha256(tkey, encrypted)
|
|
|
+ let newStrTwo = CryptoJS.enc.Base64.stringify(CryptoJS.enc.Utf8.parse(tiv + encrypted + mac));
|
|
|
+ return newStrTwo
|
|
|
+ }
|
|
|
+ /** aes解密
|
|
|
+ * @param state true 存包长 false /r/n
|
|
|
+ */
|
|
|
+ static Decrypt(word, tkey, appid, state = true) {
|
|
|
+
|
|
|
+ let en = CryptoJS.enc.Base64.parse(word).toString(CryptoJS.enc.Utf8);
|
|
|
+ let newStrOne = en.substr(16)
|
|
|
+ let temp = newStrOne.substr(0, newStrOne.length - 64)
|
|
|
+ let de = temp
|
|
|
+
|
|
|
+ let key = CryptoJS.enc.Utf8.parse(tkey);
|
|
|
+ let iv = CryptoJS.enc.Utf8.parse(tkey.substr(0, 16));
|
|
|
+
|
|
|
+ var decrypt = CryptoJS.AES.decrypt(de, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.Pkcs7 });
|
|
|
+ // LogUtil.log('decrypt ', decrypt)
|
|
|
+ var decryptedStr = CryptoJS.enc.Utf8.stringify(decrypt)
|
|
|
+ decryptedStr = decryptedStr.toString()
|
|
|
+
|
|
|
+ // LogUtil.log('decryptedStr ', decryptedStr)
|
|
|
+ let newStrThree = ''
|
|
|
+ if (state) {
|
|
|
+ newStrThree = decryptedStr.slice(16).replace(new RegExp("(.*)" + appid), '$1')
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ newStrThree = decryptedStr.slice(16).split('\r\n')[0]
|
|
|
+ }
|
|
|
+ return newStrThree
|
|
|
+ }
|
|
|
+
|
|
|
+ /** for php pack( N , length ) */
|
|
|
+ static pack(len: number) {
|
|
|
+ var buf: ArrayBuffer = new ArrayBuffer(4);
|
|
|
+ var dataView = new DataView(buf);
|
|
|
+ dataView.setUint32(0, len)
|
|
|
+ // LogUtil.log('dataView ', dataView)
|
|
|
+ let str2 = this.ab2str(buf)
|
|
|
+
|
|
|
+ // let utf8decoder = new TextDecoder();
|
|
|
+ // let str2 = utf8decoder.decode(buf)
|
|
|
+ // LogUtil.log('str2 ', str2)
|
|
|
+
|
|
|
+ // let utf8encoder = new TextEncoder();
|
|
|
+ // let str3 = utf8encoder.encode(str2)
|
|
|
+ // LogUtil.log("str3:", str3)
|
|
|
+
|
|
|
+ // let str4 = utf8decoder.decode(str3)
|
|
|
+ // LogUtil.log('str4 ', str4)
|
|
|
+
|
|
|
+ // let aa = fun_aes.CryptoJS.enc.Utf8.parse(str2)
|
|
|
+ // LogUtil.log('aa ', aa)
|
|
|
+ return str2
|
|
|
+ }
|
|
|
+
|
|
|
+ static Utf8ArrayToStr(array) {
|
|
|
+ var out, i, len, c;
|
|
|
+ var char2, char3;
|
|
|
+
|
|
|
+ out = "";
|
|
|
+ len = array.length;
|
|
|
+ i = 0;
|
|
|
+ while (i < len) {
|
|
|
+ c = array[i++];
|
|
|
+ switch (c >> 4) {
|
|
|
+ case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
|
|
|
+ // 0xxxxxxx
|
|
|
+ out += String.fromCharCode(c);
|
|
|
+ break;
|
|
|
+ case 12: case 13:
|
|
|
+ // 110x xxxx 10xx xxxx
|
|
|
+ char2 = array[i++];
|
|
|
+ out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
|
|
|
+ break;
|
|
|
+ case 14:
|
|
|
+ // 1110 xxxx 10xx xxxx 10xx xxxx
|
|
|
+ char2 = array[i++];
|
|
|
+ char3 = array[i++];
|
|
|
+ out += String.fromCharCode(((c & 0x0F) << 12) |
|
|
|
+ ((char2 & 0x3F) << 6) |
|
|
|
+ ((char3 & 0x3F) << 0));
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return out;
|
|
|
+ }
|
|
|
+
|
|
|
+ //UTF-16转UTF-8
|
|
|
+ static utf16ToUtf8(s) {
|
|
|
+ if (!s) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ var i, code, ret = [], len = s.length;
|
|
|
+ for (i = 0; i < len; i++) {
|
|
|
+ code = s.charCodeAt(i);
|
|
|
+ if (code > 0x0 && code <= 0x7f) {
|
|
|
+ //单字节
|
|
|
+ //UTF-16 0000 - 007F
|
|
|
+ //UTF-8 0xxxxxxx
|
|
|
+ ret.push(s.charAt(i));
|
|
|
+ } else if (code >= 0x80 && code <= 0x7ff) {
|
|
|
+ //双字节
|
|
|
+ //UTF-16 0080 - 07FF
|
|
|
+ //UTF-8 110xxxxx 10xxxxxx
|
|
|
+ ret.push(
|
|
|
+ //110xxxxx
|
|
|
+ String.fromCharCode(0xc0 | ((code >> 6) & 0x1f)),
|
|
|
+ //10xxxxxx
|
|
|
+ String.fromCharCode(0x80 | (code & 0x3f))
|
|
|
+ );
|
|
|
+ } else if (code >= 0x800 && code <= 0xffff) {
|
|
|
+ //三字节
|
|
|
+ //UTF-16 0800 - FFFF
|
|
|
+ //UTF-8 1110xxxx 10xxxxxx 10xxxxxx
|
|
|
+ ret.push(
|
|
|
+ //1110xxxx
|
|
|
+ String.fromCharCode(0xe0 | ((code >> 12) & 0xf)),
|
|
|
+ //10xxxxxx
|
|
|
+ String.fromCharCode(0x80 | ((code >> 6) & 0x3f)),
|
|
|
+ //10xxxxxx
|
|
|
+ String.fromCharCode(0x80 | (code & 0x3f))
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return ret.join('');
|
|
|
+ }
|
|
|
+ //UTF-8转UTF-16
|
|
|
+ static utf8ToUtf16(s) {
|
|
|
+ if (!s) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ var i, codes, bytes, ret = [], len = s.length;
|
|
|
+ for (i = 0; i < len; i++) {
|
|
|
+ codes = [];
|
|
|
+ codes.push(s.charCodeAt(i));
|
|
|
+ if (((codes[0] >> 7) & 0xff) == 0x0) {
|
|
|
+ //单字节 0xxxxxxx
|
|
|
+ ret.push(s.charAt(i));
|
|
|
+ } else if (((codes[0] >> 5) & 0xff) == 0x6) {
|
|
|
+ //双字节 110xxxxx 10xxxxxx
|
|
|
+ codes.push(s.charCodeAt(++i));
|
|
|
+ bytes = [];
|
|
|
+ bytes.push(codes[0] & 0x1f);
|
|
|
+ bytes.push(codes[1] & 0x3f);
|
|
|
+ ret.push(String.fromCharCode((bytes[0] << 6) | bytes[1]));
|
|
|
+ } else if (((codes[0] >> 4) & 0xff) == 0xe) {
|
|
|
+ //三字节 1110xxxx 10xxxxxx 10xxxxxx
|
|
|
+ codes.push(s.charCodeAt(++i));
|
|
|
+ codes.push(s.charCodeAt(++i));
|
|
|
+ bytes = [];
|
|
|
+ bytes.push((codes[0] << 4) | ((codes[1] >> 2) & 0xf));
|
|
|
+ bytes.push(((codes[1] & 0x3) << 6) | (codes[2] & 0x3f));
|
|
|
+ ret.push(String.fromCharCode((bytes[0] << 8) | bytes[1]));
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return ret.join('');
|
|
|
+ }
|
|
|
+
|
|
|
+ // ArrayBuffer转为字符串,参数为ArrayBuffer对象
|
|
|
+ static ab2str(buf: ArrayBuffer) {
|
|
|
+ return String.fromCharCode.apply(null, new Uint8Array(buf));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ static Uint8ArrayToString(fileData) {
|
|
|
+ var dataString = "";
|
|
|
+ for (var i = 0; i < fileData.length; i++) {
|
|
|
+ dataString += String.fromCharCode(fileData[i]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return dataString
|
|
|
+ }
|
|
|
+
|
|
|
+ static stringToUint8Array(str) {
|
|
|
+ var arr = [];
|
|
|
+ for (var i = 0, j = str.length; i < j; ++i) {
|
|
|
+ arr.push(str.charCodeAt(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ var tmpUint8Array = new Uint8Array(arr);
|
|
|
+ return tmpUint8Array
|
|
|
+ }
|
|
|
+
|
|
|
+ // 字符串转为ArrayBuffer对象,参数为字符串
|
|
|
+ static str2ab(str) {
|
|
|
+ var buf = new ArrayBuffer(str.length); // 每个字符占用2个字节
|
|
|
+ var bufView = new Uint8Array(buf);
|
|
|
+ for (var i = 0, strLen = str.length; i < strLen; i++) {
|
|
|
+ bufView[i] = str.charCodeAt(i);
|
|
|
+ }
|
|
|
+ return buf;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static options = {
|
|
|
+ default_key_size: 2048,
|
|
|
+ default_public_exponent: new Uint8Array([0x01, 0x00, 0x01])
|
|
|
+ }
|
|
|
+
|
|
|
+ /*rsa加密*/
|
|
|
+ static RSAEncrypt(word) {
|
|
|
+ //LogUtil.log("JSEncrypt",window['JSEncrypt'])
|
|
|
+ let jsb = new window['JSEncrypt'](this.options)
|
|
|
+
|
|
|
+ //公钥
|
|
|
+ var publicString = '-----BEGIN PUBLIC KEY-----\n' +
|
|
|
+ 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuwz5V8wt525dMS+A9wOd\n' +
|
|
|
+ 'NAjvKgxdyoXYuZSlAJEXLhvJlaXwFCKEsUg/qBBeo4nrRnwaFAjG7ItqbCWR9Ozv\n' +
|
|
|
+ '6oY5tMYQnFFK82XkMGbKm1gG0z9vYKhcNYgHZHi+QKAw4tLLWXWO/QBTGelEXptD\n' +
|
|
|
+ 'azlNmdM+8wHOknTcMuIyjc9Yo5qCoNsCJpA465vnREiBezBbKB3rSw+LmrRcZcFk\n' +
|
|
|
+ 's8hmGtjpabcQ8sCxco7mRzVh6/DomNWfNm7hUP6shrrJirwjQtaS51grlScj8KhN\n' +
|
|
|
+ 'h+kBoiI4Ad0Xz0GHasK5hAMf3sXDsN61r0An8KTfa/nsYSJDwogPIKkeKAsmw9Df\n' +
|
|
|
+ 'EQIDAQAB\n' +
|
|
|
+ '-----END PUBLIC KEY-----'
|
|
|
+ jsb.setPublicKey(publicString)
|
|
|
+ // 加密内容
|
|
|
+ let encrypted = jsb.encrypt(word)
|
|
|
+ return encrypted
|
|
|
+ }
|
|
|
+
|
|
|
+ static RSAEncryptLong(word) {
|
|
|
+ // console.log(window['JSEncrypt'])
|
|
|
+ let jsb = new window['JSEncrypt'](this.options);
|
|
|
+
|
|
|
+ //公钥
|
|
|
+ var publicString = '-----BEGIN PUBLIC KEY-----\n' +
|
|
|
+ 'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuwz5V8wt525dMS+A9wOd\n' +
|
|
|
+ 'NAjvKgxdyoXYuZSlAJEXLhvJlaXwFCKEsUg/qBBeo4nrRnwaFAjG7ItqbCWR9Ozv\n' +
|
|
|
+ '6oY5tMYQnFFK82XkMGbKm1gG0z9vYKhcNYgHZHi+QKAw4tLLWXWO/QBTGelEXptD\n' +
|
|
|
+ 'azlNmdM+8wHOknTcMuIyjc9Yo5qCoNsCJpA465vnREiBezBbKB3rSw+LmrRcZcFk\n' +
|
|
|
+ 's8hmGtjpabcQ8sCxco7mRzVh6/DomNWfNm7hUP6shrrJirwjQtaS51grlScj8KhN\n' +
|
|
|
+ 'h+kBoiI4Ad0Xz0GHasK5hAMf3sXDsN61r0An8KTfa/nsYSJDwogPIKkeKAsmw9Df\n' +
|
|
|
+ 'EQIDAQAB\n' +
|
|
|
+ '-----END PUBLIC KEY-----'
|
|
|
+ jsb.setPublicKey(publicString);
|
|
|
+ // 加密内容
|
|
|
+ let encrypted = jsb.encryptLong(word);
|
|
|
+ return encrypted;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*rsa解密*/
|
|
|
+ // static RSADecrypt(word) {
|
|
|
+ // // LogUtil.log(window['JSEncrypt'])
|
|
|
+ // let jsb = new JSEncrypt(this.options)
|
|
|
+
|
|
|
+ // //私钥
|
|
|
+ // var privateString = '-----BEGIN RSA PRIVATE KEY-----\n' +
|
|
|
+ // 'MIIEowIBAAKCAQEAuwz5V8wt525dMS+A9wOdNAjvKgxdyoXYuZSlAJEXLhvJlaXw\n' +
|
|
|
+ // 'FCKEsUg/qBBeo4nrRnwaFAjG7ItqbCWR9Ozv6oY5tMYQnFFK82XkMGbKm1gG0z9v\n' +
|
|
|
+ // 'YKhcNYgHZHi+QKAw4tLLWXWO/QBTGelEXptDazlNmdM+8wHOknTcMuIyjc9Yo5qC\n' +
|
|
|
+ // 'oNsCJpA465vnREiBezBbKB3rSw+LmrRcZcFks8hmGtjpabcQ8sCxco7mRzVh6/Do\n' +
|
|
|
+ // 'mNWfNm7hUP6shrrJirwjQtaS51grlScj8KhNh+kBoiI4Ad0Xz0GHasK5hAMf3sXD\n' +
|
|
|
+ // 'sN61r0An8KTfa/nsYSJDwogPIKkeKAsmw9DfEQIDAQABAoIBAFonN6pkY5+O5uXE\n' +
|
|
|
+ // '8pCbslIZGESY7z+kYT+Y8CokxBpaFD/HWb4qoO/dVakIMsT5vWcce2k6jb4GuAVl\n' +
|
|
|
+ // '2kJFTKEpjnidmfXtjIVhj6jwciiLNcbtZR4eJ0s5w+5d77ywOL+qP45fhcpVNLhh\n' +
|
|
|
+ // 'YK2EgesVFFzWnxl6vniCUHtJ4HnOKHJCnLNP8Jv7v8yWqRhdPv+OSnXc/f8M5Nq4\n' +
|
|
|
+ // 'zXIjZIf84sQdI9MAZ4IUv3yUnhQIGCX/ilLiOb+u8Z02DnImpwrSurm4SWOl/W7F\n' +
|
|
|
+ // 'jz1LHonOnFNvoICwJUlwmSHVbSxOG4dHSxs45dSHizCxIbPyHNW0sF/u5EHz2cmw\n' +
|
|
|
+ // 'ZIrtmh0CgYEA91DZBmRS8f6ELIPTozOd9c9OOiW0Mn0njG2Hf59tRkUNcAVnrdT6\n' +
|
|
|
+ // '1v0ziD1tnprBCQr7NKzJiU3ds4qR/Vfza2F9M894CIX3HZLZomrP+Kr0xqeogxfy\n' +
|
|
|
+ // 'IVQ3n6aCIR2lKG2zBuxJJCp3UhGjS1NOOvcVqK9F+0Py6LHRG7SAoMsCgYEAwZ5l\n' +
|
|
|
+ // 'Q2x/V9vDf3KMsQf/5noaPrxgoTH9py4JgCwK6ab9M8BtAsAZ4xs6RUd6XEMeGsv4\n' +
|
|
|
+ // 'rLKKZhR0vMNnec/wHb3tNEFMihKsGkgCrycl4sJQIJsNX30bungrrC2XZUEAqN9g\n' +
|
|
|
+ // '1IbDKAiq6l+0YQVC+742FZ6t7IgjrgV/lj7g0BMCgYEAkSeZiT/e0vvAFeR1lecY\n' +
|
|
|
+ // 'wgofbs9sWOnOCYTLr2MiHskunt39QTCs3PwVf9QV/63yuF0CnaMAUp8qDVO6Zch2\n' +
|
|
|
+ // 'LUM12e/eEpqWNHxZUhOA5wFn0yTaKb8nNNqaHxD6dXdR1U21cs3CDAEEsV16yx4k\n' +
|
|
|
+ // '30TgKHZfC5+Q9XRQOAOUL0sCgYBcq/u78cphuwYvkhxU/4c0QW0eafu2K79ErXxO\n' +
|
|
|
+ // 'pMX0X8EBbDDBCEFbukSBtFyUnGtkWAyGXE5x3YiicMSuQSCkm6tVP4vq6lUFn0Hp\n' +
|
|
|
+ // 'o8s2ZdsEQDJ+adtDvRDqMEguZpZyPbiTAI2YM83asEQdy+7rn3czkeedNuwc9vTC\n' +
|
|
|
+ // 'bQYdkQKBgAqApiDmh84iMQUv5DQ2ks4Ddv/jpuYp/wELTN59n+IvP7BfdkOVBcYR\n' +
|
|
|
+ // 'Z1MZNo9fAIdF700ijKQKKgR1r5iOHiBo4A4DybxN3FHyS348BDbuh/dg2Z6307iS\n' +
|
|
|
+ // 'cNCq6ajhNeTtMy2E14DEdinp/7l2o87OpAR2cGRFBEi+f2RRQ2p0\n' +
|
|
|
+ // '-----END RSA PRIVATE KEY-----'
|
|
|
+ // jsb.setPrivateKey(privateString)
|
|
|
+ // // 解密内容
|
|
|
+ // let encrypted = jsb.decrypt(word)
|
|
|
+ // return encrypted
|
|
|
+ // }
|
|
|
+
|
|
|
+ static getLocalTime(nS) {
|
|
|
+ return new Date(parseInt(nS) * 1000).toLocaleString().replace(/:\d{1,2}$/, ' ');
|
|
|
+ }
|
|
|
+}
|