先说需求:
需要后端和前端通信需要将数据加密后传输
前端 <-> 加密数 <-> 后端
总的来说PHP的使用时最简单的,坑最少,当之无愧世界上最好的语言
以下是代码实现
以下代码实现统一使用参数
AES加密算法 32位秘钥key (通过给定秘钥取md5值获得) 123456 16位初始向量iv 秘钥key的md5值前16位 加密数据 "123456789"
1、PHP实现AES加密解密
使用函数 openssl_encrypt
和 openssl_decrypt
<?php class AESCipher { private $method; private $key; private $iv; /** * AESCipher constructor. * @param string $method * @param string $key 采用32位长度,正好是一个md5值 * @param string $iv CBC模式,需要16位长度 */ public function __construct($method, $key, $iv = "") { $this->key = $key; $this->method = $method; $this->iv = $iv; } // 加密数据 public function encrypt($plain_text) { return openssl_encrypt($plain_text, $this->method, $this->key, 0, $this->iv); } // 解密数据 public function decrypt($cipher_text) { return openssl_decrypt($cipher_text, $this->method, $this->key, 0, $this->iv); } } /** * 以下是测试代码 */ // ECB 模式 function test_ecb($key, $data) { $aes = new AESCipher("AES-256-ECB", $key); $cipher_text = $aes->encrypt($data); echo $cipher_text . PHP_EOL; // 7J0VfbEYF0XdLnLuA1b4Fw== $plain_text = $aes->decrypt($cipher_text); echo $plain_text . PHP_EOL; // 123456789 } // CBC 模式 function test_cbc($key, $data, $iv) { $aes = new AESCipher("AES-256-CBC", $key, $iv); $cipher_text = $aes->encrypt($data); echo $cipher_text . PHP_EOL; // sfH6iGxc01TkIaOUN77hQQ== $plain_text = $aes->decrypt($cipher_text); echo $plain_text . PHP_EOL; // 123456789 } $key = "123456"; $md5_key = md5($key); $iv = substr($md5_key, 0, 16); $data = "123456789"; test_ecb($md5_ky, $data); test_cbc($md5_key, $data, $iv);
参考
https://www.php.net/manual/zh/function.openssl-encrypt.php
2、Python3实现AES加密解密
安装模块
import base64 from Crypto.Cipher import AES from Crypto.Util.Padding import pad, unpad from md5util import md5 class AESCipher(object): def __init__(self, key, mode, **kwargs): """ :param key: 16 (AES-128) 24 (AES-192) 32 (AES-256) :param mode: 模式 :param kwargs: iv 初始向量 MODE_CBC 模式使用 必须是16字节 """ self.key = key self.mode = mode self.kwargs = kwargs def _get_aes(self): """TypeError: decrypt() cannot be called after encrypt()""" return AES.new(self.key.encode('utf-8'), self.mode, **self.kwargs) def encrypt(self, plain_text): # 选择pkcs7补全 pad_pkcs7 = pad(plain_text.encode('utf-8'), AES.block_size) encrypt_data = self._get_aes().encrypt(pad_pkcs7) return str(base64.b64encode(encrypt_data), encoding='utf-8') def decrypt(self, cipher_text): padded_data = self._get_aes().decrypt(base64.b64decode(cipher_text.encode('utf-8'))) return str(unpad(padded_data, AES.block_size), encoding='utf-8') def main(): key = "123456" md5_key = md5(key) aes_str = "123456789" # ECB 模式 ecb_cipher = AESCipher(md5_key, mode=AES.MODE_ECB) cipher_text = ecb_cipher.encrypt(aes_str) print(cipher_text) # 7J0VfbEYF0XdLnLuA1b4Fw== print(ecb_cipher.decrypt(cipher_text)) # CBC 模式 cbc_cipher = AESCipher(md5_key, mode=AES.MODE_CBC, IV=md5_key[0:16].encode()) cipher_text = cbc_cipher.encrypt(aes_str) print(cipher_text) # sfH6iGxc01TkIaOUN77hQQ== print(cbc_cipher.decrypt(cipher_text)) if __name__ == '__main__': main()
参考
https://www.dlitz.net/software/pycrypto/api/current/
使用Python实现AES(256)加密,ECB模式,pkcs7补全(AES五种加密模式(CBC、ECB、CTR、OCF、CFB))
3、JavaScript实现AES加密解密
安装
npm install crypto-js
crypto-js使用的时候有点坑,不像别的语言实现,它会将你传入的key转为它需要的对象,所以要先调用下parse
函数
var CryptoJS = require("crypto-js"); // 辅助函数 function md5(data) { return CryptoJS.MD5(data).toString(); } // 传入key之前要调用,不然结果不对 function parseKey(key) { return CryptoJS.enc.Utf8.parse(key); } // 加密过程 function encrypt(mode, plainText, key, iv = null) { const uKey = parseKey(key); const uIv = parseKey(iv); return CryptoJS.AES.encrypt(plainText, uKey, { iv: uIv, mode: mode, padding: CryptoJS.pad.Pkcs7 } ).toString(); } // 解密过程 function decrypt(mode, cipherText, key, iv = null) { const uKey = parseKey(key); const uIv = parseKey(iv); let bytes = CryptoJS.AES.decrypt(cipherText, uKey, { iv: uIv, mode: mode, padding: CryptoJS.pad.Pkcs7 } ); return bytes.toString(CryptoJS.enc.Utf8); } function test() { const key = '123456'; const md5Key = md5(key); const iv = md5Key.substr(0, 16); const data = '123456789'; // ECB 模式 let cipherText = encrypt(CryptoJS.mode.ECB, data, md5Key); console.log(cipherText); // 7J0VfbEYF0XdLnLuA1b4Fw== let plainText = decrypt(CryptoJS.mode.ECB, cipherText, md5Key); console.log(plainText); // CBC 模式 cipherText = encrypt(CryptoJS.mode.CBC, data, md5Key, iv); console.log(cipherText); // sfH6iGxc01TkIaOUN77hQQ== plainText = decrypt(CryptoJS.mode.CBC, cipherText, md5Key, iv); console.log(plainText); } test();
参考