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

2023-12-02

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

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

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;
 }

我有什么明显遗漏的东西吗?


The 密码反馈 (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") and someString.getBytes("UTF-8")。当你这样做时,要保持一致。

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

  • 在 Java 中,您假设 IV 写在密文前面,然后一起编码,但在 Python 中,您永远不会对 IV 执行任何操作。我猜你发布的代码不完整。

  • CFB 模式使用一个至关重要的不同的如果密钥保持不变,则每次 IV。如果您不更改每次加密的 IV,您将创建一个多次密码本,使攻击者即使在不知道密钥的情况下也能推断出明文。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 AES-CFB 在 python 中加密并在 Java 中解密 的相关文章

随机推荐