您现在的位置是:首页 > 技术教程 正文

PHP开发日志 ━━ 基于PHP和JS的AES相互加密解密方法详解(CryptoJS) 适合CryptoJS4.0和PHP8.0

admin 阅读: 2024-03-16
后台-插件-广告管理-内容页头部广告(手机)

最近客户在做安全等保,需要后台登录密码采用加密方式,原来用个base64变形一下就算了,现在不行,一定要加密加key加盐~~
前端使用Cypto-JS加密,传输给后端使用PHP解密,当然,前端虽然有key有盐,但这玩意儿用点心的话,也不过是障眼法而已。

在这里插入图片描述

更新:才发现今年初就已经写好模块,用私钥公钥非对称RSA的方式来实现加密登录。。。我去,老年痴呆越来越明显了
PHP开发日志 ━━ jsrsasign、jsencrypt、php实现前后端数据的RSA加密和解密

本文更侧重与前端使用纯js实现加密,后端使用php解密,前后端对称。

HTML(index.html)代码

DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <script src="./jquery.min.js">script> <script src="./crypto-js.min.js">script> head> <body> <div style="margin: 0;text-align:center;"> <h2>基于PHP和JS的AES相互加密解密方法详解(CryptoJS)h2> div> <div style="margin:0 18%;"> <h4>注意说明:h4> <ul> <li>1. 首先引入CryptoJS包中的aes.js和pad-zeropadding.jsli> <li>2. 其次引入了jquery.min.js和自己封装的function.js(内容主要是加密解密函数)li> <li>3. 加密解密过程中的向量和密钥必须保持一致li> <li>4. 进行加密的数据(字符串类型):{"username":"1001","password":"123456","terminal":"PC"}li> <li>5. 加密结果是变化的在这不写(变化的原因是因为密钥取得是当前时间)li> <li>6. 具体详情可读代码(注释完整)li> ul> div> <div style="margin:0 18%;"> <h4>加密测试:h4> <ul> <li>进行加密的数据(字符串类型):{"username":"1001","password":"123456","terminal":"PC"}li> <li id="encrypt_key">li> <li id="encrypt_string">li> ul> div> <div style="margin:0 18%;"> <h4>解密测试:h4> <ul> <li> 进行解密密的数据(字符串类型、PHP端生成):8bkd/doBOrG3+pTEGkRwk9A3ZLrzXtf10E6Nn9CSoHXRXHydM7xt7PllPhUSItuK8ciF5g6UZ7DruCPQCVNZIJzI4ZHyUMJlV2aHyqMhbEoyS3pK6lPs1MsOeU/H7BZ5 li> <li id="decrypt_key">解密的密钥(PHP端生成):li> <li id="decrypt_string">JS解密后字符串:li> ul> div> <script> //********************************加密********************************** //获取当前时间戳13位 + 3位字符 var timestamp = new Date().getTime().toString() + "WZH"; //加密密钥16位 var encrypt_key = timestamp; //加密向量16位 var iv = 'ZZWBKJ_ZHIHUAWEI'; //要加密的数据 var encrypt_string = '{"username":"1001","password":"123456","terminal":"PC"}'; //加密后密文(加密函数在function.js文件中) var encrypted_string = encrypt(encrypt_string, encrypt_key, iv); $("#encrypt_key").text("JS加密密钥:" + encrypt_key); $("#encrypt_string").text("JS加密后字符串:" + encrypted_string); //********************************结束********************************** //********************************解密********************************** //解密密钥16位(解密向量同上) var decrypt_key = '20180227110419WB'; //解密密文字符串 var decrypt_string = "8bkd/doBOrG3+pTEGkRwk9A3ZLrzXtf10E6Nn9CSoHXRXHydM7xt7PllPhUSItuK8ciF5g6UZ7DruCPQCVNZIJzI4ZHyUMJlV2aHyqMhbEoyS3pK6lPs1MsOeU/H7BZ5"; var decrypted_string = decrypt(decrypt_string, decrypt_key, iv); $("#decrypt_key").text("解密的密钥(PHP端生成):" + decrypt_key); $("#decrypt_string").text("JS解密后字符串:" + decrypted_string); //********************************结束********************************** script> body> html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

界面效果

在这里插入图片描述

JS(funciton.js)代码

/** * 接口数据加密函数 * @param str string 需加密的json字符串 * @param key string 加密key(16位) * @param iv string 加密向量(16位) * @return string 加密密文字符串 */ function encrypt(str, key, iv) { //密钥16位 var key = CryptoJS.enc.Utf8.parse(key); //加密向量16位 var iv = CryptoJS.enc.Utf8.parse(iv); var encrypted = CryptoJS.AES.encrypt(str, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.ZeroPadding }); return encrypted; } /** * 接口数据解密函数 * @param str string 已加密密文 * @param key string 加密key(16位) * @param iv string 加密向量(16位) * @returns {*|string} 解密之后的json字符串 */ function decrypt(str, key, iv) { //密钥16位 var key = CryptoJS.enc.Utf8.parse(key); //加密向量16位 var iv = CryptoJS.enc.Utf8.parse(iv); var decrypted = CryptoJS.AES.decrypt(str, key, { iv: iv, mode: CryptoJS.mode.CBC, padding: CryptoJS.pad.ZeroPadding }); return decrypted.toString(CryptoJS.enc.Utf8); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

PHP5或PHP8(index.php)代码

<?php header("Content-type:text/html;charset=utf-8"); //加密向量16位 $iv = "ZZWBKJ_ZHIHUAWEI"; //********************************解密********************************** //js加密秘钥16位 $decrypt_key = "1519699179001WZH"; //js加密密文字符串 $decrypt_data = "ngX3VuJ+b2dBmfMEk4+Q8eVGNnWeidwMZltHn78g4b8sn1i7Di8LPeNnQNQmY525LxADvJKIEpv2Vzs0w9fdlw=="; $decrypted = decrypt($decrypt_data, $decrypt_key, $iv); //解密结果 var_dump($decrypted); //exit; //********************************结束********************************** //********************************加密********************************** //PHP加密秘钥16位 $encrypt_key = date("YmdHis") . "WB"; //PHP加密数据 $arr = array('username' => '1001', 'password' => '123456', 'terminal' => 'PC'); //转换成json字符串 $encrypt_data = json_encode($arr); $encrypted = encrypt($encrypt_data, $encrypt_key, $iv); //加密结果 var_dump($encrypted); exit; //********************************结束********************************** //******************************集成函数******************************** /** * 加密字符串 * @param string $data 字符串 * @param string $key 加密key * @param string $iv 加密向量 * @return string */ function encrypt($data, $key, $iv) { //支持php5 //$encrypted = mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $data, MCRYPT_MODE_CBC, $iv); //支持php8 //$decrypted = openssl_encrypt($data, 'AES-128-CBC', $key,2, $iv); $encrypted = openssl_encrypt($data, "AES-128-CBC", $key, true, $iv); return base64_encode($encrypted); } /** * 解密字符串 * @param string $data 字符串 * @param string $key 加密key * @param string $iv 加密向量 * @return object */ function decrypt($data, $key, $iv) { //支持php5 //$decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, base64_decode($data), MCRYPT_MODE_CBC, $iv); //支持php8 //$decrypted = openssl_decrypt($data, 'AES-128-CBC', $key,2, $iv); $decrypted = openssl_decrypt(base64_decode($data), 'AES-128-CBC', $key, true, $iv); $json_str = rtrim($decrypted, "\0"); return json_decode($json_str); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64

在这里插入图片描述

其它

另一篇文章中的代码测试,基本一致

var message = "1_2_3_4_5_6_7_8_9_0";//utf8字符串,待加密 var iv = CryptoJS.lib.WordArray.random(128 / 8).toString(CryptoJS.enc.Hex);//随机生成长度为32的16进制字符串。IV称为初始向量,不同的IV加密后的字符串是不同的,加密和解密需要相同的IV。 var key = "0321ebeba1f75de2d3cd3471af7418a4";//秘钥。长度32的16进制字符串。 var cryptkey = CryptoJS.enc.Hex.parse(key);//将16进制字符串转换为 WordArray对象 //或者 //var key = "qwertyuiopasdfgh";//长度16的utf8字符串 //var cryptkey = CryptoJS.enc.Utf8.parse(key);//将utf8字符串转换为 WordArray对象 //重点是 key要转换为WordArray对象,加密时要用。 //测试 var ciphertext = aesEncrypt(message,cryptkey,iv);//加密 var decryptedMessage = aesDecrypt(ciphertext,cryptkey,iv);//解密 console.log(decryptedMessage);//1_2_3_4_5_6_7_8_9_0 // jQuery('#a').val(ciphertext.toString()); // jQuery('#b').val(CryptoJS.enc.Hex.parse(iv).toString()); //** 加密 ** //var ciphertext = CryptoJS.AES.encrypt(message, key, cfg); //params: 注意参数key为WordArray对象 //return: 密码对象 或者 密码对象Base64字符串 function aesEncrypt(message,key,iv){ var ciphertext = CryptoJS.AES.encrypt(message, key, { iv: CryptoJS.enc.Hex.parse(iv), mode: CryptoJS.mode.CBC, padding:CryptoJS.pad.Pkcs7 }); return ciphertext;//密码对象(Obejct类型,非WordArray类型),Base64编码。 //return ciphertext.toString();//密码对象的Base64字符串 } //** 解密 ** //var plaintext = CryptoJS.AES.decrypt(ciphertext, key, cfg); //params: 注意参数ciphertext 必须为 Base64编码的对象或者字符串。 function aesDecrypt(ciphertext,key,iv){ var decrypted = CryptoJS.AES.decrypt(ciphertext,key,{ iv: CryptoJS.enc.Hex.parse(iv), mode: CryptoJS.mode.CBC, padding:CryptoJS.pad.Pkcs7 }); return decrypted.toString(CryptoJS.enc.Utf8);//WordArray对象转utf8字符串 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44

文章来源:

  • 基于PHP和JS的AES相互加密解密方法详解(CryptoJS)
  • 基于PHP7和JS的AES相互加密解密方法详解2(CryptoJS)
  • php:aes加密使用mcrypt_decrypt能解开,openssl_decrypt却解不开,what?
  • CryptoJS中AES256(CBC)加密算法简单使用
  • HTML使用 crypto-js-AES 加密
标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索