1. AES通过明文与密文

javascript的aes加密解密实现

var text = "123456";
var passphrase = "0123456789asdfgh";  // 十六位字符串作为密钥

var encryptedMessage = CryptoJS.AES.encrypt(text, passphrase).toString();
console.log("encrypt:", encryptedMessage);  
// encrypt: U2FsdGVkX18hyuQnNnZyAe7emBZrUR/YGmy90QN1DI4=

var decryptedMessage = CryptoJS.AES.decrypt(encryptedMessage, passphrase).toString(CryptoJS.enc.Utf8);

console.log("decrypt:", decryptedMessage);
// decrypt: 123456

CryptoJS的AES算法默认是CBC模式和PKCS#7填充,密钥大小为256位,IV是128位块大小。

python的aes加密解密实现(pycryptodome)

import base64
from Crypto.Cipher import AES
from Crypto import Random

def pad(s):
    return s + (16 - len(s) % 16) * chr(16 - len(s) % 16).encode()

def unpad(s):
    return s[0:-ord(s[len(s)-1:])]

def bytes_to_key(data, salt, output=48):
    assert len(salt) == 8, len(salt)
    data += salt
    key = md5(data).digest()
    final_key = key
    while len(final_key) < output:
        key = md5(key + data).digest()
        final_key += key
    return final_key[:output]

def encrypt(data, passphrase):
    salt = Random.new().read(8)
    key_iv = bytes_to_key(passphrase, salt, 32+16)
    key = key_iv[:32]
    iv = key_iv[32:]
    aes = AES.new(key, AES.MODE_CBC, iv)
    cipherbyte = base64.b64encode(b"Salted__" + salt + aes.encrypt(pad(data)))
    return cipherbyte

def decrypt(data, passphrase):
    data = base64.b64decode(data)
    assert data[:8] == b'Salted__'
    salt = data[8:16]
    key_iv = bytes_to_key(passphrase, salt, 32+16)
    key = key_iv[:32]
    iv = key_iv[32:]
    aes = AES.new(key, AES.MODE_CBC, iv)
    plainbyte = unpad(aes.decrypt(data[16:]))
    return plainbyte

if __name__ == '__main__':
    data = b'123456'
    passphrase = b'0123456789asdfgh'

    # encrypt_data = encrypt(data, passphrase)
    # print('encrypt_data:', encrypt_data)

    encrypt_data = b"U2FsdGVkX18hyuQnNnZyAe7emBZrUR/YGmy90QN1DI4="

    decrypt_data = decrypt(encrypt_data, passphrase)
    print('decrypt_data:', decrypt_data)

python的aes加密解密实现(cryptography)

import os
import base64
from hashlib import md5
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes

def pad(s):
    return s + (16 - len(s) % 16) * chr(16 - len(s) % 16).encode()

def unpad(s):
    return s[0:-ord(s[len(s)-1:])]

def bytes_to_key(data, salt, output=48):
    assert len(salt) == 8, len(salt)
    data += salt
    key = md5(data).digest()
    final_key = key
    while len(final_key) < output:
        key = md5(key + data).digest()
        final_key += key
    return final_key[:output]

def encrypt(data, passphrase):
    salt = os.urandom(8)
    key_iv = bytes_to_key(passphrase, salt, 32+16)
    key = key_iv[:32]
    iv = key_iv[32:]
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
    encryptor = cipher.encryptor()
    encrypted = encryptor.update(pad(data)) + encryptor.finalize()
    cipherbyte = base64.b64encode(b"Salted__" + salt + encrypted)
    return cipherbyte

def decrypt(data, passphrase):
    data = base64.b64decode(data)
    assert data[:8] == b'Salted__'
    salt = data[8:16]
    key_iv = bytes_to_key(passphrase, salt, 32+16)
    key = key_iv[:32]
    iv = key_iv[32:]
    cipher = Cipher(algorithms.AES(key), modes.CBC(iv))
    decryptor = cipher.decryptor()
    plainbyte = unpad(decryptor.update(data[16:]) + decryptor.finalize())
    return plainbyte

if __name__ == '__main__':
    data = b'123456'
    passphrase = b'0123456789asdfgh'

    encrypt_data = encrypt(data, passphrase)
    print('encrypt_data:', encrypt_data)

    #encrypt_data = b"U2FsdGVkX18hyuQnNnZyAe7emBZrUR/YGmy90QN1DI4="
    decrypt_data = decrypt(encrypt_data, passphrase)
    print('decrypt_data:', decrypt_data)



2. AES通过密钥与偏移量

javascript的aes加密解密实现

function Str2Bytes(str) {
    var bytes = [];
    for (var i = 0; i < str.length; i++) {
        var charCode = str.charCodeAt(i);
        bytes.push(charCode);
    }
    return bytes;
}

function Bytes2Str(bytes) {
    var str = "";
    for (var i = 0; i < bytes.length; i++) {
        var char = String.fromCharCode(bytes[i]);
        str = str + char;
    }
    return str;
}

/**
 * 密码 `0` 填充
 * @param {string} key     密码
 * @param {Number} keySize 填充长度, 值: 16,32,64,128
 */
function fillKey(key, keySize) {
    keySize = keySize || 128;
    var buffer = new ArrayBuffer(keySize);
    var view = new Int8Array(buffer);

    var bytes = Str2Bytes(key);
    var keys = Int8Array.from(bytes);
    if (keys.length < view.length) {
        for (var i = 0; i < view.length; i++) {
            if (keys[i] == undefined) {
                view[i] = 48;
            } else {
                view[i] = keys[i];
            }
        }
        return Bytes2Str(view);
    } else {
        return key;
    }
}

function unfillKey(key) {
    var bytes = [];
    var keys = Str2Bytes(key);
    for (var i = 0; i < keys.length; i++) {
        if (keys[i] != 48) {
            bytes.push(keys[i]);
        }
    }
    return Bytes2Str(bytes);
}

var text = "123456";

//var key = fillKey(key, 16);
//var iv = fillKey(iv, 16);

const key = CryptoJS.enc.Utf8.parse("1234123412ASDFGH");  //十六位字符串作为密钥
const iv = CryptoJS.enc.Utf8.parse('ASDFGH1234123412');   //十六位字符串作为偏移量

var encrypted = CryptoJS.AES.encrypt(text, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
});

// 转换为字符串
encryptedStr = encrypted.toString();
console.log("encrypted:", encryptedStr);
// encrypted:D6AFFsf6c1De2EsRDEOPBA==

var decrypted = CryptoJS.AES.decrypt(encryptedStr, key, {
    iv: iv,
    mode: CryptoJS.mode.CBC,
    padding: CryptoJS.pad.Pkcs7
});

// 转换为 utf8 字符串
decryptedStr = CryptoJS.enc.Utf8.stringify(decrypted);
console.log("decrypted:", decryptedStr);
// decrypted:123456

python的aes加密解密实现(pycryptodome)

import base64
from Crypto.Cipher import AES
from Crypto import Random

def pad(s):
    return s + (16 - len(s) % 16) * chr(16 - len(s) % 16).encode()

def unpad(s):
    return s[0:-ord(s[len(s)-1:])]

def encrypt(data, key, iv):
    aes = AES.new(key, AES.MODE_CBC, iv)
    cipherbyte = base64.b64encode(aes.encrypt(pad(data)))
    return cipherbyte

def decrypt(data, key, iv):
    data = base64.b64decode(data)
    aes = AES.new(key, AES.MODE_CBC, iv)
    plainbyte = unpad(aes.decrypt(data))
    return plainbyte

if __name__ == '__main__':
    key = b"1234123412ASDFGH"
    iv = b"ASDFGH1234123412"

    data = b"123456"

    # encrypt_data = encrypt(data, key, iv)
    # print("encrypt_data", encrypt_data)

    encrypt_data = b"D6AFFsf6c1De2EsRDEOPBA=="

    decrypt_data = decrypt(encrypt_data, key, iv)
    print('decrypt_data:', decrypt_data)