Js:Crypto与PHP:openssl AES加密解密

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
}

这只是一次心得 也许有误导他人的地方

虚心求教 有错误的地方欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值