Java移植到Python中的AES加密
免责声明:这是我继承的不安全加密,所有相关人员都知道这一点。我在这里试图做的是摆脱这个遗留系统的第一步,这个遗留系统有着比这更大的问题
我有一个Java现有系统,我正在尝试将其移植到Python,以执行AES加密:
public static String encrypt(String text, SecretKey secretKey) throws Exception {
byte[] cipherText = null;
String encryptedString = null;
// get an RSA cipher object and print the provider
Cipher cipher = Cipher.getInstance(SYMMETRIC_KEY_ALGORITHM); // AES
// encrypt the plain text using the public key
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
cipherText = cipher.doFinal(text.getBytes());
encryptedString = Base64.getEncoder().encodeToString(cipherText);
return encryptedString;
}
我遇到的问题是,尝试使用Python和加密库从以下位置获得相同的AES设置组合,以获得相同的结果:
我从看似已不存在的PyCrypto库中看到了很多例子,我甚至无法在我的Windows系统上安装,更不用说工作了
我最近的尝试是这样的,我确实得到了加密,但与Java AES输出不匹配:
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
key = b'Some random key '
cipher = Cipher(algorithms.AES(key), modes.GCM(b'000000000000'))
encryptor = cipher.encryptor()
ct = encryptor.update(ENC_MESSAGE)
base64EncodedStr = base64.b64encode(ct).decode('utf-8')
print('BASE64:', base64EncodedStr)
根据rzwitserloot的答案进行更新
我将模式从GCM更改为ECB,现在使用Python得到的结果几乎相同。首先,更新后的代码如下所示:
key = b'Some random key '
cipher = Cipher(algorithms.AES(key), modes.ECB())
encryptor = cipher.encryptor()
ct = encryptor.update(PLAINTEXT.encode('utf-8'))
base64EncodedStr = base64.b64encode(ct).decode('utf-8')
print('Encrypted:', base64EncodedStr)
参考(即Java)输出的长度为1004个字符,而Python输出的长度仅为984个字符。但它们匹配的Python字符串末尾最多有3个字符:
我确实检查了解密,发现两个加密的文本字符串解密为相同的明文
最后更新:
填充物是问题所在。我将代码更新为使用PKCS7填充,如下所示,现在我从Java和Python获得了相同的结果:
from cryptography.hazmat.primitives import padding as symmetric_padding
padder = symmetric_padding.PKCS7(algorithms.AES.block_size).padder()
padded_data = padder.update(PLAINTEXT.encode('utf-8')) + padder.finalize()
ct = encryptor.update(padded_data)
# 1 楼答案
你需要两个版本之间的所有内容都要完全相同。目前情况并非如此;解决这个问题
您的java代码使用:
对于其中的大多数,我无法告诉你;您粘贴的代码不足。例如,AES密钥大小以及密钥是否完全相同?我不知道——你告诉我。你是如何制作
SecretKey key
对象的我对python不太熟悉,但看起来确实需要对其进行base64编码,然后再次解码。那是。。不,不要那样做。你的java代码编码就是这样。你的python代码应该是base64编码,仅此而已
我很确定python也默认为PKCS5P
这就留下了java和python之间100%不匹配的编码模式,给出了粘贴的少量代码,以及构造键的方式。如果加密的文本不是直接的ASCII码,那么字符集编码也可能会造成差异
这是加密的。一个微小的差异和输出将是完全不同的