在python中加密并使用AES-CFB在Java中解密

我知道一个与此非常类似的问题( 如何在Python中加密并在Java中解密? )但我有一个不同的问题。

我的问题是,我无法正确解密Java。 尽管使用了正确的密钥和IV,我仍然在解密后获得垃圾字符。 我在Java中没有任何编译/运行时错误或exception,因此我相信我正在使用正确的参数进行解密。

Python加密代码 –

from Crypto.Cipher import AES import base64 key = '0123456789012345' iv = 'RandomInitVector' raw = 'samplePlainText' cipher = AES.new(key,AES.MODE_CFB,iv) encrypted = base64.b64encode(iv + cipher.encrypt(raw)) 

Java解密代码 –

 private static String KEY = "0123456789012345"; public static String decrypt(String encrypted_encoded_string) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException { String plain_text = ""; try{ byte[] encrypted_decoded_bytes = Base64.getDecoder().decode(encrypted_encoded_string); String encrypted_decoded_string = new String(encrypted_decoded_bytes); String iv_string = encrypted_decoded_string.substring(0,16); //IV is retrieved correctly. IvParameterSpec iv = new IvParameterSpec(iv_string.getBytes()); SecretKeySpec skeySpec = new SecretKeySpec(KEY.getBytes("UTF-8"), "AES"); Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding"); cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv); plain_text = new String(cipher.doFinal(encrypted_decoded_bytes));//Returns garbage characters return plain_text; } catch (Exception e) { System.err.println("Caught Exception: " + e.getMessage()); } return plain_text; } 

我有什么遗漏吗?

密码反馈(CFB)操作模式是一系列模式。 它由段大小(或寄存器大小)参数化。 PyCrypto的默认段大小为8位 ,Java(实际上是OpenJDK)的默认段大小与块大小相同 (AES为128位)。

如果你想在pycrypto中使用CFB-128,你可以使用AES.new(key, AES.MODE_CFB, iv, segment_size=128) 。 如果你想在Java中使用CFB-8,你可以使用Cipher.getInstance("AES/CFB8/NoPadding");


现在我们已经解决了这个问题,你还有其他问题:

  • 始终指定您正在使用的字符集,因为它可以在不同的JVM之间进行更改: new String(someBytes, "UTF-8")someString.getBytes("UTF-8") 。 当你这样做时,要保持一致。

  • 永远不要使用String来存储二进制数据( new String(encrypted_decoded_bytes); )。 您可以直接复制字节: IvParameterSpec iv = new IvParameterSpec(Arrays.copyOf(encrypted_decoded_bytes, 16));cipher.doFinal(Arrays.copyOfRange(encrypted_decoded_bytes, 16, encrypted_decoded_bytes.length))

  • 在Java中,您假设IV是在密文之前编写然后一起编码的,但在Python中,您从不对IV做任何事情。 我猜你发布了不完整的代码。

  • 如果密钥保持不变,则每次使用不同的 IV时,CFB模式至关重要。 如果您不为每次加密更改IV,您将创建一个多时间平台,使攻击者即使不知道密钥也可以推断出明文。

Interesting Posts