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
}

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

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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于您的问题,我可以为您提供以下答案: 在PHP 7.2及以上版本中,可以通过openssl扩展实现AES加密。具体实现方式如下: 1. AES加密 ```php function aesEncrypt($data, $key, $iv) { $encrypted = openssl_encrypt($data, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv); return base64_encode($encrypted); } ``` 其中,$data为待加密的数据,$key为加密密钥,$iv为初始化向量,函数返回值为加密后的数据(base64编码)。 2. AES解密 ```php function aesDecrypt($data, $key, $iv) { $encrypted = base64_decode($data); $decrypted = openssl_decrypt($encrypted, 'AES-128-CBC', $key, OPENSSL_RAW_DATA, $iv); return $decrypted; } ``` 其中,$data为待解密的数据(base64编码),$key为解密密钥,$iv为初始化向量,函数返回值为解密后的数据。 通过以上函数实现的AES加密可以与JS进行互通,具体实现方式可以参考以下示例: 1. JS加密 ```javascript function aesEncrypt(data, key, iv) { var cipher = crypto.createCipheriv('aes-128-cbc', key, iv); var encrypted = cipher.update(data, 'utf8', 'base64'); encrypted += cipher.final('base64'); return encrypted; } ``` 其中,data为待加密的字符串,key为加密密钥,iv为初始化向量,函数返回值为加密后的数据(base64编码)。 2. JS解密 ```javascript function aesDecrypt(data, key, iv) { var decipher = crypto.createDecipheriv('aes-128-cbc', key, iv); var decrypted = decipher.update(data, 'base64', 'utf8'); decrypted += decipher.final('utf8'); return decrypted; } ``` 其中,data为待解密的数据(base64编码),key为解密密钥,iv为初始化向量,函数返回值为解密后的数据。 注意事项: 1. 在PHP中,$key和$iv必须为16位长度的字符串,可以通过以下方式生成: ```php $key = openssl_random_pseudo_bytes(16); $iv = openssl_random_pseudo_bytes(16); ``` 2. 在JS中,key和iv必须为Buffer类型,可以通过以下方式生成: ```javascript var key = crypto.randomBytes(16); var iv = crypto.randomBytes(16); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值