JavaScript 和 Python 的 AES 前后端加解密

本文采用 aes-cbc 模式 + Pkcs7 填充方案,在加密和解密时需要一个初始化向量(Initialization Vector, IV)和秘钥,每次加密前或解密后,使用初始化向量与明文或密文进行异或运算。

JavaScript 依赖 CryptoJS

Google Code:
https://code.google.com/archive/p/crypto-js/downloads
百度网盘:
https://pan.baidu.com/s/1Qn_8sLVNx6DRdFWBeZ0U_A

Python 依赖

  • cryptography
  • Crypto
  • binascii

实现代码

python

from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import algorithms
from Crypto.Cipher import AES
from binascii import b2a_hex, a2b_hex


class AesCrypto(object):
    def __init__(self, key):
        self.key = key.encode('utf-8')[:16]
        self.iv = self.key
        self.mode = AES.MODE_CBC

    @staticmethod
    def pkcs7_padding(data):
        if not isinstance(data, bytes):
            data = data.encode()
        padder = padding.PKCS7(algorithms.AES.block_size).padder()
        padded_data = padder.update(data) + padder.finalize()
        return padded_data

    def encrypt(self, plaintext):
        cryptor = AES.new(self.key, self.mode, self.iv)
        plaintext = plaintext
        plaintext = self.pkcs7_padding(plaintext)
        ciphertext = cryptor.encrypt(plaintext)
        return b2a_hex(ciphertext).decode('utf-8')

    def decrypt(self, ciphertext):
        cryptor = AES.new(self.key, self.mode, self.iv)
        plaintext = cryptor.decrypt(a2b_hex(ciphertext))
        return bytes.decode(plaintext).rstrip('\0')


aes = AesCrypto('ddfbccae-b4c4-11')
encrypted = aes.encrypt('恭喜你,123,gooood!')
print(encrypted)
decrypted = aes.decrypt(encrypted)
print(decrypted)

JavaScript 封装

let CryptoJS = require('../utils/aes.js')

/**
 * 加密
 */
function aes_encrypt(plaintext, key, iv) {
  key = CryptoJS.enc.Utf8.parse(key)
  iv = CryptoJS.enc.Utf8.parse(iv)
  let srcs = CryptoJS.enc.Utf8.parse(plaintext)
  let encrypted = CryptoJS.AES.encrypt(srcs, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  return encrypted.ciphertext.toString()
}

/**
 * 解密
 */
function aes_decrypt(ciphertext, key, iv) {
  key = CryptoJS.enc.Utf8.parse(key)
  iv = CryptoJS.enc.Utf8.parse(iv)
  let hex_string = CryptoJS.enc.Hex.parse(ciphertext)
  let srcs = CryptoJS.enc.Base64.stringify(hex_string)
  let decrypt = CryptoJS.AES.decrypt(srcs, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
  })
  decrypt = decrypt.toString(CryptoJS.enc.Utf8)
  return decrypt.toString()
}

JavaScript 调用
key 和 iv 使用 16 位长度字符串

let plaintext = '恭喜你,123,goood!'
let key = "ddfbccae-b4c4-11"
let iv = "ddfbccae-b4c4-11"

let ciphertext = aes_encrypt(plaintext, key, iv)
console.log('ciphertext', ciphertext)

plaintext = aes_decrypt(ciphertext, key, iv)
console.log('plaintext', plaintext)

你可能感兴趣的:(python,JavaScript)