当前位置: 首页 > 面试题库 >

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

微生慈
2023-03-14
问题内容

我的问题是,我无法在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;
 }

有什么明显的我想念的东西吗?


问题答案:

的操作的密码反馈(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")。当您这样做时,请保持一致。

  • 切勿使用字符串存储二进制数据(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进行任何操作。我猜您发布的代码不完整。

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



 类似资料:
  • 问题内容: 基于Golang关于CFB解密的文档,我写了一个最小的工作示例来解密使用AES CFB加密的字符串,然后使用python3编码的base 64。 当邮件在Golang中加密(使用Golang doc示例中的加密功能)时,golang解密工作正常。但是,当我使用python crypto包在python脚本中加密消息时,我无法在golang脚本中成功解密它。我没有得到正确的字节。 两种A

  • 在用于aes加密和解密的python脚本中 但是相同的iv、消息和密钥在python和js中产生不同的加密消息, JavaScript与python解密兼容的问题是什么? 两者都使用了aes.mode_cbc,并且假设两者都使用了Pkcs7填充。硬编码iv现在是随机生成的

  • 问题内容: 我正在尝试在java中加密数据并在ruby中解密数据。 我的代码是…用Java加密 结果是 我希望在Ruby中解密(加密的字符串) Ruby代码是…(错误) 我希望得到 但它返回错误 我认为问题是cipher.padding和key / iv的类型。但是我不知道如何完成红宝石代码。 请让我知道如何完成此代码。 谢谢。 问题答案: Ruby代码有两个问题。 首先,应该使用AES 128时

  • 我已经设法使它能够处理不包含og a-zA-Z0-9之外的字符和一些特殊字符的文本,但如果我使用丹麦字母,如ielouangØ,解密的文本会显示?而不是实际的字母。所有文件都保存为UTF-8,头字符集=UTF-8 Javascript - input: "tester for php: 我试过选项0,OPENSSL_ZERO_PADDING和OPENSSL_RAW_DATA,结果相同。有人能帮我吗

  • 我正在尝试使用Javascript和CryptoJS复制Java应用程序中使用的加密。我不太确定应该如何复制SecretKeySpec,因为CryptoJS似乎需要一个字符串作为密钥。 下面是我需要在JS中复制的Java加密代码: 到目前为止,我的JS代码: 此外,密码的最终输出是一个加密的字节数组。CryptoJS的最终输出似乎是一个带有密文的对象。有没有办法以字节数组的形式获取输出? 我现在唯