在Java中解密AES编码的消息(用Python加密) [英] Decrypt an AES encoded message (encrypted in Python) in Java
问题描述
我要解密Java中的AES加密邮件。我一直在尝试各种算法/模式/填充选项从标准图书馆和 BouncyCastle 。没有运气: - (
I want to decrypt an AES encrypted message in Java. I’ve been trying various Algorithm/Mode/Padding options from the standard library and from BouncyCastle. No luck :-(
加密实体是用Python编写的,已经在生产中了,加密的消息已经消失了,所以我不能轻易改变那部分Python代码如下所示:
The encrypting entity is written in Python and is already in production. Encrypted messages have already gone out, so I cannot easily change that part. The Python code looks like this:
from Crypto.Cipher import AES
import base64
import os
import sys
BLOCK_SIZE = 16
PADDING = '\f'
pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * PADDING
EncodeAES = lambda c, s: base64.b64encode(c.encrypt(pad(s)))
DecodeAES = lambda c, e: c.decrypt(base64.b64decode(e)).rstrip(PADDING)
secret = 'XXXXXXXXXXXXXXXX'
cipher = AES.new(secret)
clear='test'
encoded = EncodeAES(cipher, clear)
print 'Encrypted string:>>{}<<'.format(encoded)
decoded = DecodeAES(cipher, encoded)
print 'Decrypted string:>>{}<<'.format(decoded)
显然使用AES,我想我必须使用ECB模式。但我还没有找到一个工作在Java端的填充模式。如果输入符合块大小,并且没有发生填充,我可以在Java中解密消息。如果邮件需要填充,则解密失败。
Obviously AES is used, and I figured out that I have to use ECB mode. But I have not found a padding mode that works on the Java side. If the input fits within the block size and no padding is happening, I can decrypt the message in Java. If the message needs to be padded, decryption fails.
要解密的Java代码如下所示:
The Java code to decrypt looks like this:
public class AESPaddingTest {
private enum Mode {
CBC, ECB, CFB, OFB, PCBC
};
private enum Padding {
NoPadding, PKCS5Padding, PKCS7Padding, ISO10126d2Padding, X932Padding, ISO7816d4Padding, ZeroBytePadding
}
private static final String ALGORITHM = "AES";
private static final byte[] keyValue = new byte[] { 'X', 'X', 'X', 'X',
'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' };
@BeforeClass
public static void configBouncy() {
Security.addProvider(new BouncyCastleProvider());
}
@Test
public void testECBPKCS5Padding() throws Exception {
decrypt("bEpi03epVkSBTFaXlNiHhw==", Mode.ECB,
Padding.PKCS5Padding);
}
private String decrypt(String valueToDec, Mode modeOption,
Padding paddingOption) throws GeneralSecurityException {
Key key = new SecretKeySpec(keyValue, ALGORITHM);
Cipher c = Cipher.getInstance(ALGORITHM + "/" + modeOption.name() + "/" + paddingOption.name());
c.init(Cipher.DECRYPT_MODE, key);
byte[] decValue = c.doFinal(valueToDec.getBytes());
String clear = new String(Base64.encodeBase64(decValue));
return clear;
}
}
引发的错误是:
javax.crypto.IllegalBlockSizeException:当
使用padded cipher解密时,输入长度必须为16的倍数
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
任何想法?
推荐答案
字符( \f
)。我不知道一个标准的填充方案这样做。因此,我建议您在Java端选择 NoPadding
,并准备剥离 \f
字符
You are padding with form-feed characters (\f
). I'm not aware of a standard padding scheme that does this. As a result, I suggest you opt for NoPadding
on the Java side and be prepared to strip \f
characters from the plaintext you get after decryption.
因为你能够解密一个非填充的明文,所以它证明你有两个相同的密钥材料(这是一个常见的我很高兴我们可以删除列表)。
Since you are able to decrypt a non-padded plaintext then it demonstrates you have the same key material on both sides (which is a common issue that I'm glad we can strike off the list).
阅读 Python文档,它看起来像ECB模式是默认选择。因此,请确保在Java端使用此方法。
Reading the Python documentation, it looks like ECB-mode is chosen by default. So make sure you use this on the Java side.
这篇关于在Java中解密AES编码的消息(用Python加密)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!