php和javascript通用的数据加解密踩坑记

  • baagee 发布于 2018-05-01 18:26:55
  • 分类:PHP
  • 1713 人围观
  • 3 人喜欢

最新我想搞个小应用***,前端用的vue,后端是自己写的php api框架,前后端分离,api数据传输想保密,虽然用上了https,但是数据还是可以被抓包看见的,心里不安,于是就想数据加密传输,那就要使用javascript和php通用的加解密方式了,js加密的数据可以通过php解密,php加密的数据可以被js解密。昨晚找了一下,可以使用crypto-js和php的mcrypt。于是就动手写代码了,在vue项目里新建一个js文件:

import CryptoJS from 'crypto-js'

const KEY = '5NmhVXqSro6j9eyNO3bzw';
const IV = '1234567890123456';

function getAesString(data, key, iv) {//加密
    var key_hash = CryptoJS.MD5(key).toString();
    var key = CryptoJS.enc.Utf8.parse(key_hash);  
    var iv = CryptoJS.enc.Utf8.parse(iv);
    var encrypted = CryptoJS.AES.encrypt(data, key,
        {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        });
    return encrypted.toString();    //返回的是base64格式的密文
}
function getDAesString(encrypted, key, iv) {//解密
    var key_hash = CryptoJS.MD5(key).toString();
    var key = CryptoJS.enc.Utf8.parse(key_hash);
    var iv = CryptoJS.enc.Utf8.parse(iv);
    var decrypted = CryptoJS.AES.decrypt(encrypted, key,
        {
            iv: iv,
            mode: CryptoJS.mode.CBC,
            padding: CryptoJS.pad.Pkcs7
        });
    return decrypted.toString(CryptoJS.enc.Utf8);
}
export function getEAES(data) { //加密
    var encrypted = getAesString(data, KEY, IV);
    // var encrypted1 = CryptoJS.enc.Utf8.parse(encrypted);
    return encrypted;
}
export function getDAES(data) {//解密
    return getDAesString(data, KEY, IV);
}

php对应加解密的代码:

<?php 
class Tools{
	private $md5Key='';
	private $iv='';
	public function __construct($key,$iv){
		$this->md5Key = md5($key);
		$this->iv=$iv;
	}

	public function encode($data){
		// 加密
		$cryptText = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $this->md5Key, $data, MCRYPT_MODE_CBC, $this->iv);
		return base64_encode($cryptText);
	}

	public function decode($data){
		// 解密
		$cryptText = base64_decode($data); 
		return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $this->md5Key, $cryptText, MCRYPT_MODE_CBC, $this->iv));
	}
}

$key='5NmhVXqSro6j9eyNO';
$iv='1234567890123456';

$tools=new Tools($key,$iv);
$password='sdgjwgoiuio';
$encode=$tools->encode($password);
var_dump($encode);
var_dump($tools->decode($encode));

在我windows上,装的php5.5,拿来测试是没问题的,但是今天我弄到centos上,装的php7.2,告诉我没有mcrypt_encrypt方法!!!!!我屮艸芔茻!我昨晚找了好久,调了好久代码才实现通用的,结果tmd在高php版本上不能用了,【php官方表示由于php_mcrypt扩展太过于老旧已经被移除,建议使用php_openssl扩展来替代】然后我就开始找代替方案了,经过调试,终于成功了,废话少说直接上代码:

class secretTools
{
    private $md5Key = '';
    private $iv = '';

    public function __construct($key, $iv)
    {
        $this->md5Key = md5($key);
        $this->iv = $iv;
    }

    public function encode($data)
    {
        // 加密
        $cryptText = openssl_encrypt($data,"aes-256-cbc",$this->md5Key,OPENSSL_RAW_DATA,$this->iv);
        return base64_encode($cryptText);
    }

    public function decode($data)
    {
        // 解密
        $cryptText = base64_decode($data);
        return trim(openssl_decrypt($cryptText, 'aes-256-cbc', $this->md5Key, OPENSSL_RAW_DATA,$this->iv));
    }
}

就是这么简单啊!

最后查看成果图:


可以看到表单数据加密传输,同时php也解密出来原始数据了。

注意:

openssl加密不推荐补零,所以对应的js加解密也不需要补零,对应的padding为CryptoJS.pad.pkcs7,而不是ZeroPadding。

如果php要想使用mcrypt系列函数,那对应的js文件里padding对应的就是CryptoJS.pad.ZeroPadding了


标签: PHP javascript

评论

点击图片切换
还没有评论,快来抢沙发吧!