AES/ECB/PKCS5Padding加密:Java与Python结果不一致求助
AES加密Java与Python实现结果不一致的解决方案
问题说明
参照Java的AES加密逻辑编写Python版本代码,但两者输出的加密结果完全不同,排查多日未解决,需技术协助。
Java原加密代码
public String encrypt(String strToEncrypt, String myKey) throws Exception { try { MessageDigest sha = null; byte[] key = myKey.getBytes("UTF-8"); sha = MessageDigest.getInstance("SHA-1"); key = sha.digest(key); key = Arrays.copyOf(key, 32); // 将SHA-1的20字节结果补0到32字节 SecretKeySpec secretKey = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))); } catch (Exception e) { throw e; } }
原Python实现代码
import base64 import hashlib from Crypto.Cipher import AES def encrypt(str_to_encrypt, my_key): try: sha = hashlib.sha1() sha.update(my_key.encode('utf-8')) key = sha.digest() key = key[:16] # 错误:仅取前16字节,对应AES-128,与Java逻辑不符 cipher = AES.new(key, AES.MODE_ECB) byte_array = str_to_encrypt.encode("UTF-8") padded_data = pad(byte_array, AES.block_size) encrypted_data = cipher.encrypt(padded_data) return base64.b64encode(encrypted_data).decode('utf-8') except Exception as e: raise e def pad(byte_array: bytearray, block_size: int): pad_len = block_size - len(byte_array) % block_size return byte_array + (bytes([pad_len]) * pad_len) # 测试示例 my_key = "mySecretKey" str_to_encrypt = "This is the string to encrypt" encrypted_string = encrypt(str_to_encrypt, my_key) print(encrypted_string)
结果对比
- Java加密结果:
0xfLbMxzLp0B1v10jgySMuPsNn74Ow55x2R6GUyY9XE= - 原Python加密结果:
jhfQIBB0vFeerfp1LdhZwIW/Bj6VXsPy84YWkci8oPA=
问题核心原因
- 密钥长度不匹配:Java代码中,SHA-1生成20字节密钥后,通过
Arrays.copyOf(key, 32)将密钥补0填充至32字节,使用AES-256加密;而原Python代码仅取前16字节,使用AES-128加密,这是结果不一致的根本原因。 - 填充逻辑两者一致(均为PKCS5Padding),此部分无问题。
修正后的Python代码
import base64 import hashlib from Crypto.Cipher import AES def encrypt(str_to_encrypt, my_key): try: sha = hashlib.sha1() sha.update(my_key.encode('utf-8')) key = sha.digest() # 对应Java的Arrays.copyOf(key, 32):将20字节SHA-1结果补0至32字节 key = key.ljust(32, b'\x00') cipher = AES.new(key, AES.MODE_ECB) byte_array = str_to_encrypt.encode("UTF-8") padded_data = pad(byte_array, AES.block_size) encrypted_data = cipher.encrypt(padded_data) return base64.b64encode(encrypted_data).decode('utf-8') except Exception as e: raise e def pad(byte_array: bytes, block_size: int): pad_len = block_size - len(byte_array) % block_size return byte_array + (bytes([pad_len]) * pad_len) # 测试示例 my_key = "mySecretKey" str_to_encrypt = "This is the string to encrypt" encrypted_string = encrypt(str_to_encrypt, my_key) print(encrypted_string) # 输出与Java一致:0xfLbMxzLp0B1v10jgySMuPsNn74Ow55x2R6GUyY9XE=
内容的提问来源于stack exchange,提问作者Shubham
相关产品推荐
相关产品推荐

