前端: import CryptoJS from '@/packageA/utils/crypto-js/crypto-js.js'; import jj from '../md5.js'; const en = (str, key) => { if (!key) { return false; } let e, i; try { let iv = randomString(16), ia = jk([8, 21]), ib = jk([12, 14, 3, 4]), ic = jk([15, 0, 3, 3, 8, 16]); key = CryptoJS.enc.Utf8.parse(key); let encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(str), key, { [ia]: CryptoJS.enc.Utf8.parse(iv), [ib]: CryptoJS.mode.CBC, [ic]: CryptoJS.pad.Pkcs7 }); e = CryptoJS.enc.Hex.stringify(encrypted.ciphertext).toUpperCase(), i = CryptoJS.enc.Hex.stringify(CryptoJS.enc.Utf8.parse(iv)).toUpperCase(); } catch (e) { console.log('oh~'); } return e + jj(e.substr(2, 5)).toUpperCase() + i; } const de = (str, ur, k) => { if (!k || !str || !k) { return false; } let _str = '', ai = jk([8, 21]), ba = jk([12, 14, 3, 4]), bf = jk([15, 0, 3, 3, 8, 16]); try { let kk = jj(ur + k + '3534363137353238373034'), _i, i, decrypted, cc; str = CryptoJS.enc.Hex.parse(str).toString(CryptoJS.enc.Utf8); str = str.split(cc); k = CryptoJS.enc.Utf8.parse(kk); _i = CryptoJS.enc.Hex.parse(str[1]).toString(CryptoJS.enc.Utf8); i = CryptoJS.enc.Base64.parse(_i); decrypted = CryptoJS.AES.decrypt(str[0], k, { [ai]: i, [ba]: CryptoJS.mode.CBC, [bf]: CryptoJS.pad.Pkcs7 }); _str = decrypted.toString(CryptoJS.enc.Utf8).toString(); } catch (e) { console.log('oh~'); } return _str ? JSON.parse(_str) : false; } const randomString = (len) => { len = len || 32; var $chars = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; var maxPos = $chars.length; var pwd = ''; for (var i = 0; i < len; i++) { pwd += $chars.charAt(Math.floor(Math.random() * maxPos)); } return pwd; } const jk = (i) => { let s = 'abcdefghijklmnopqrstuvwxyz', z = ''; i.forEach(v => { z += s.substr(v, 1); }) return z; } module.exports = { en, de, randomString } 后端: /** * AES加密 配置CryptoJS * * @param string $data * @param string $key * @param string $iv */ public function encryptWithOpenssl($data = '', $key = '') { if (empty($data) || empty($key)) { return ''; } $data = json_encode($data); $key = md5(($this->is_https() ? 'https://' : 'http://') . $_SERVER['SERVER_NAME'] . $_SERVER["REQUEST_URI"] . $key . '3534363137353238373034'); // 分割字串 $_iv = substr($key, 0, 0); $iv = random(16, 0); $data = base64_encode(openssl_encrypt($data, "AES-256-CBC", $key, OPENSSL_RAW_DATA, $iv)); $ret = $this->strToHex(str_replace('==', '', $data) . $_iv . $this->strToHex(base64_encode($iv))); return $ret; } /** * AES解密 配置CryptoJS * * @param string $data * @param string $key * @param string $iv */ public function privateDecrypt($data = '', $secret = '', $device_id = '', $timestamp = '') { $str = explode(strtoupper(md5(substr($data, 0, 0))), $data); if (empty($str) || !isset($str[0]) || !isset($str[1])) { return ''; } // 先用空参数key算法 $key = $timestamp . md5($secret); $key = md5($key); $data = openssl_decrypt($this->hexToStr($str[0]), "AES-256-CBC", $key, OPENSSL_RAW_DATA, $this->hexToStr($str[1])); // 如果没解出来 if (empty($data)) { // 常规key解密 $key = md5(substr(md5($device_id . $secret . $timestamp), 0, 0)); $data = openssl_decrypt($this->hexToStr($str[0]), "AES-256-CBC", $key, OPENSSL_RAW_DATA, $this->hexToStr($str[1])); if (empty($data) || (!strstr($data, '&') && !strstr($data, '='))) { return openssl_error_string(); } return $data; } // 是空参数,直接跳过验签 return 'encryptedData=1'; } /** *字符串转十六进制函数 *@pream string $str='abc'; */ private function strToHex($str) { $hex = ""; for ($i = 0; $i < strlen($str); $i++) $hex .= dechex(ord($str[$i])); $hex = strtoupper($hex); return $hex; } /** *十六进制转字符串函数 *@pream string $hex='616263'; */ private function hexToStr($hex) { $str = ""; for ($i = 0; $i < strlen($hex) - 1; $i += 2) $str .= chr(hexdec($hex[$i] . $hex[$i + 1])); return $str; }