![](/img/trans.png)
[英]Different encryption in Crypto.js and .NET Cryptography using AES
[英]Encryption with Crypto.js and pycrypto generates different encryption cipher text
我正在嘗試使用Crypto.js
使用其AES
算法在 Node 中生成加密文本。 它在 Js 中用於加密和解密。 同樣,我嘗試使用pycrypto
在Python中實現相同的功能,它在python中都進行了加密和解密。但是當我想使用來自JS的加密密文在Python中解密時,問題就出現了。問題是JS中生成的加密文本不同根據 Python 中生成的內容。
這是基於 JS 的 AES 用法:
import CryptoJS from "crypto-js";
let str = "lol";
let salt = "ABCDEFGHIJKLMNOP";
let key = "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP";
salt = CryptoJS.enc.Hex.parse(salt);
key = CryptoJS.enc.Hex.parse(key);
const options = {
iv: salt,
padding: CryptoJS.pad.ZeroPadding,
mode: CryptoJS.mode.CFB,
};
// function to encrypt the string
function encrypt(str, salt, key) {
const cipher = CryptoJS.AES.encrypt(str, key, options);
console.log("cipher", CryptoJS.enc.Hex.stringify(cipher.ciphertext));
return cipher.ciphertext.toString(CryptoJS.enc.Base64);
}
// function to decrypt the string
function decrypt(str, salt, key) {
const cipher = CryptoJS.AES.decrypt(str, key, options);
return cipher.toString(CryptoJS.enc.Utf8);
}
const encrypted = encrypt(str, salt, key);
console.log("encrypted", encrypted);
const decrypted = decrypt(encrypted, salt, key);
console.log("decrypted", decrypted);
// OUTPUT
// encrypted sd4Xpz/ws8x2j+cgF17t6A==
// decrypted lol
這是基於 Python 的 AES 用法:
from Crypto.Cipher import AES
from base64 import b64encode, b64decode
str = "lol";
salt = b"ABCDEFGHIJKLMNOP";
key = "ABCDEFGHIJKLMNOPABCDEFGHIJKLMNOP";
enc_dec_method = 'utf-8'
def encrypt(str_to_enc, str_key, salt):
aes_obj = AES.new(str_key.encode('utf-8'), AES.MODE_CFB, salt)
hx_enc = aes_obj.encrypt(str_to_enc.encode('utf8'))
df = b64encode(hx_enc)
mret = b64encode(hx_enc).decode(enc_dec_method)
return mret
def decrypt(str_to_dec, str_key, salt):
aes_obj = AES.new(str_key.encode('utf-8'), AES.MODE_CFB, salt)
str_tmp = b64decode(str_to_dec.encode(enc_dec_method))
str_dec = aes_obj.decrypt(str_tmp)
mret = str_dec.decode(enc_dec_method)
return mret
test_enc_text = encrypt(str, key, salt)
test_dec_text = decrypt(test_enc_text, key, salt)
print(f"Encrypted Text: {test_enc_text}")
print(f"Decrypted Text: {test_dec_text}")
# OUTPUT
# Encrypted Text: o9XB
# Decrypted Text: lol
我在這里缺少什么關鍵概念可以幫助彌合兼容性差距?
這些代碼不兼容,因為:
Key 和 IV 不是十六進制編碼的,因此不能在 CryptoJS 代碼中使用十六進制編碼器。 如果要像在 Python 代碼中一樣應用 Utf-8 編碼,則必須改用 Utf-8 編碼器。
salt = CryptoJS.enc.Utf8.parse(salt); key = CryptoJS.enc.Utf8.parse(key);
CFB 是一種不需要填充的 stream 密碼模式。 但是,在當前的 CryptoJS 代碼中,使用了零填充 ( CryptoJS.pad.ZeroPadding
)。 相反,必須禁用填充(這不會隱式發生,與 Python 代碼不同):
padding: CryptoJS.pad.NoPadding,
CFB 配置有一個附加參數,即段大小,它指定每個加密步驟加密的位數。 CryptoJS 代碼僅支持一種段大小,即 128 位。 使用 PyCryptodome,可以配置段大小,默認使用 8 位。 為了兼容性,必須將其更改為 128 位:
aes_obj = AES.new(str_key.encode('utf-8'), AES.MODE_CFB, salt, segment_size=128)
通過這些更改,兩個代碼都兼容。
測試:兩種代碼都為以下明文提供以下密文:
plaintext: The quick brown fox jumps over the lazy dog
ciphertext: m0T/7e04eV49RTcgd7KtwHxSOavNzHNwlrvjt1YmmHidBy4rHS0oovclKQ==
請注意,您所說的鹽實際上是初始化向量( IV )。 術語鹽更常用於密鑰派生函數(如 PBKDF2)的上下文中。
關於安全性:用於 salt 和 IV 的值可用於測試,但在現實世界場景中,必須為每次加密的 IV 應用隨機字節序列,它必須與密文一起傳遞給解密方(一般串聯)。
此外,作為密鑰,不必使用密碼,而是使用隨機字節序列。 密碼短語(當然是強密碼)只能與密鑰派生 function 結合使用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.