先說需求:
需要後端和前端通信需要将資料加密後傳輸
前端 <-> 加密數 <-> 後端
總的來說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.php2、 Python 3實作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();
JavaScript 加解密庫(crypto-js)