建议和反馈

请填写你的反馈内容

问答 > 密码学 > 问答详情
已解决

用Java解密AES编码的消息(用Python加密)10LK

我想用Java解密AES加密消息。 我一直在尝试标准库BouncyCastle中的各种算法/模式/填充选项。 没有运气 :-(

加密实体是用Python编写的,现在已经投入生产。 加密的消息已经消失,所以我不能轻易改变那部分。 Python代码如下所示:

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解密消息。 如果需要填充消息,则解密失败。

要解密的Java代码如下所示:

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:使用填充密码解密时,输入长度必须是16的倍数

有任何想法吗?


2019-08-20
0
请先登陆或注册

香辣xg2019-08-20

您使用换页字符填充( \f )。 我不知道这样做的标准填充方案。 因此,我建议您在Java端选择NoPadding,并准备从解密后获得的明文中删除\f字符。

既然你能够解密非填充明文,那么它就会证明你在两边都有相同的密钥材料(这是一个常见的问题,我很高兴我们可以从列表中删除)。

阅读Python文档 ,默认选择ECB模式。 因此,请确保在Java端使用它。

投一票
评论(0)
赞赏(0)
邀请

感谢您的善举,每一次解答会成为新人的灯塔,回答被采纳后获得20算力和相应的LK币奖励