crypto 是一个纯javascript写的加密算法类库 ,可以非常方便地在 javascript 进行 MD5、SHA1、SHA2、SHA3、RIPEMD-160 哈希散列,进行 AES、DES、Rabbit、RC4、Triple DES 加解密。
因为需求是加密可逆,具有一定的安全性(对安全性要求不高),所以使用DES或AES即可,我用的是AES;
加密解密固定算法是相通的 只要找到对应的加解密方法加解密就可实现
在使用CryptoJS中 常见的就是WordArray对象 我们把它理解为一个新的数据类型 叫它加密数组
这里不做具体描述,使用情况就是 所有的16进制的加密key与盐 CryptoJS都需要这个类型
但是我们后端加密解密可以忽略这个WordArray对象 只需要使用16进制的key就可以了
我们先来认识几个PHP函数
openssl_encrypt 加密函数
openssl_decrypt 解密函数
hex2bin 十六进制值转ASCII字符 bin2hex 字符串转十六进制值
pack
耐心的查资料 找到两种语言对应的加密解密方式
比如
CryptoJS.enc.Hex.parse(r) 这个r是16进制值 PHP就要pack('H*',$r)
CryptoJS.AES.decrypt(n,u,{iv:rr}) ==> openssl_decrypt($u, $method, $u, 2, $rr);
解释函数注意位置
openssl_encrypt () openssl_decrypt ()
??????? key(秘钥)需要把Crypto使用的16进制值转成ASCII字符串然后再使用 也就是需要hex2bin
????????iv(盐) 需要把Crypto使用的16进制转换 也就是需要pack('H*',$rrr)
贴代码
<?php
/**
* Created by PhpStorm.
* User: f9410
* Date: 2021/10/21
* Time: 15:33
*/
class CryptoJsPHP{
/**
* @param $sstr session32
* @param $iviv 秘钥加密盐
* @param $iv 字符串解密盐
* @param $encrypt 待解密字符串
* @return string 解密后的字符串
*/
public function decrypt($sstr, $iviv, $iv, $encrypt){
$sPasswordKey = $this->pbkdf2($sstr, $iviv);
return $this->opensslDecrypt($encrypt, $sPasswordKey, $iv);
}
/**
* @param $data 待加密字符串
* @param $sstr session32
* @return string 加密后并拼接好的字符串
*/
public function encrypt($data, $sstr){
$sRand = '';
for($i=0;$i<8;$i++){
$rand = dechex(mt_rand(0x00000000, 0xffffffff) & 0xffffffff);
$sRand .= str_pad($rand, 8, '0', STR_PAD_LEFT);
}
$iv = md5(mt_rand(0,999999999));
$sPasswordKey = $this->pbkdf2($sstr, $sRand);
return $sRand . $iv . $this->opensslEncrypt($data, $sPasswordKey, $iv);
}
private function opensslEncrypt($data, $key, $iv = '', $method='AES-128-CBC'){
$iv = pack('H*',$iv);
$key = hex2bin($key);
$str = openssl_encrypt($data, $method, $key, 0, $iv);
return $str;
}
private function opensslDecrypt($encrypt, $key, $iv='', $method='AES-128-CBC'){
$iv = pack('H*',$iv);
$key = hex2bin($key);
$str = openssl_decrypt($encrypt, $method, $key, OPENSSL_ZERO_PADDING, $iv);
return $str;
}
private function pbkdf2($password, $iv){
$hasher = "sha256";
$iterations = 1000;
$outsize = 256;
$iv = pack('H*',$iv);
$key = hash_pbkdf2($hasher, $password, $iv, $iterations, 32, false);
return $key;
}
}
function JSencrypt(word) {
let s = 'dQLw7T7Plz58F1KxpUGWbnh10OJygwB9';
let r = CryptoJS.lib.WordArray.random(32);//随机32
let iviv = CryptoJS.lib.WordArray.random(16);//随机16
let iv = CryptoJS.PBKDF2(s, r, {
keySize: 4,
iterations: 1000,
hasher: CryptoJS.algo.SHA256
});
let i = CryptoJS.AES.encrypt(word, iv, {
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7,
iv: iviv
});
let l = CryptoJS.enc.Hex.stringify(r) + CryptoJS.enc.Hex.stringify(iviv) + i.ciphertext.toString(CryptoJS.enc.Base64);
return l;
}
function JSdecrypt(e) {
let o = 'dQLw7T7Plz58F1KxpUGWbnh10OJygwB9';
let t = o.substr(0, 32)//密钥加密字符串
, s = e.substr(0, 64)//密钥加密盐
, r = e.substr(64, 32)//偏移量待加密
, n = e.substr(96)//加密字符串
, u = CryptoJS.PBKDF2(t, CryptoJS.enc.Hex.parse(s), {
keySize: 4,
iterations: 1e3,
hasher: CryptoJS.algo.SHA256
})//密钥
, i = CryptoJS.AES.decrypt(n, u, {
iv: CryptoJS.enc.Hex.parse(r),//偏移量
mode:CryptoJS.mode.CBC,
})//解密开的对象
, l = i.toString(CryptoJS.enc.Utf8);
return l
}
这只是一次心得 也许有误导他人的地方
虚心求教 有错误的地方欢迎指正
|