Crypto-JS與Python的AES算法加密與解密

1. AES通過明文與密文

javascript的aes加密解密實現

var text = "123456";
var passphrase = "0123456789abcdef";  // 十六位十六進制數作爲密鑰

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

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

console.log("decrypt", decryptedMessage);

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)
    cipher = base64.b64encode(b"Salted__" + salt + aes.encrypt(pad(data)))
    return cipher

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)
    plain = unpad(aes.decrypt(data[16:]))
    return plain

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

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

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

2. AES通過密鑰與偏移量

javascript的aes加密解密實現

/**
 * 密碼 `\x00` 填充
 * @param {string} key     密碼
 * @param {Number} keySize 填充長度, 值: 128, 256
 */
function fillKey(key, keySize) {
    keySize = keySize || 128;
    var filledKey = Buffer.alloc(keySize / 8);
    var keys = Buffer.from(key);
    if (keys.length < filledKey.length) {
        for (var i = 0; i < filledKey.length; i++) {
            filledKey[i] = keys[i];
        }
    }

    return filledKey;
}

var text = "123456";
const key = CryptoJS.enc.Utf8.parse("1234123412ABCDEF");  //十六位十六進制數作爲密鑰
const iv = CryptoJS.enc.Utf8.parse('ABCDEF1234123412');   //十六位十六進制數作爲偏移量

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

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

// 轉換爲字符串
encryptedStr = encrypted.toString();
console.log("encrypted", encryptedStr);

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);

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)
    cipher = base64.b64encode(aes.encrypt(pad(data)))
    return cipher

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

if __name__ == '__main__':
    key = b"1234123412ABCDEF"
    iv = b"ABCDEF1234123412"

    data = b"123456"
    encrypt_data = encrypt(data, key, iv)
    print("encrypt_data", encrypt_data)

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章