gpt4 book ai didi

java - 用 Java 解密 AES 编码的消息(用 Python 加密)

转载 作者:行者123 更新时间:2023-11-29 05:35:11 27 4
gpt4 key购买 nike

我想用 Java 解密 AES 加密的消息。我一直在尝试 standard library 中的各种算法/模式/填充选项来自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 端的填充模式。如果输入适合 block 大小并且没有填充发生,我可以用 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: Input length must be multiple of 16 when decrypting with padded cipher

有什么想法吗?

最佳答案

感谢您提出好的问题、答案和评论。我对代码做了一些小改动,现在它对我来说就像一个魅力。

import java.security.GeneralSecurityException;
import java.security.Key;
import java.security.Security;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

import android.util.Base64;

public class AESTest {

public enum Mode {
CBC, ECB, CFB, OFB, PCBC
};

public enum Padding {
NoPadding, PKCS5Padding, PKCS7Padding, ISO10126d2Padding, X932Padding, ISO7816d4Padding, ZeroBytePadding
}

private static final String ALGORITHM = "AES";

private static final byte[] keyValue ="myKey".getBytes();


String decrypt(String valueToDec, Mode modeOption,
Padding paddingOption) throws GeneralSecurityException {



byte[] decodeBase64 = Base64.decode(valueToDec.getBytes(),0);

Key key = new SecretKeySpec(keyValue, ALGORITHM);
Cipher c = Cipher.getInstance("AES/ECB/NoPadding");
c.init(Cipher.DECRYPT_MODE, key);
byte[] encValue = c.doFinal(decodeBase64);
return new String(encValue).trim();

}

}

然后,我在我的 Android Activity 中使用了这个类,如下所示:

AESTest aes=new AESTest();
String decrypted = aes.decrypt(myCipheredText,Mode.ECB,Padding.NoPadding);

注意python代码中的secret和java代码中的mykey是一样的

关于java - 用 Java 解密 AES 编码的消息(用 Python 加密),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19763720/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com