【问题标题】:Decrypting (in python) the encrypted data using AES256 (CBC + PKCS7 padding) is resulting extra characters in the end使用AES256(CBC + PKCS7填充)解密(在python中)加密数据最终会产生额外的字符
【发布时间】:2021-01-04 20:45:34
【问题描述】:

我们正在使用下面的 java 代码来解密在 CBC 模式下使用 AES-256 和 PKCS7 填充加密的数据。

Java 代码:

import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import java.security.*;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;


public class AES256 {

    private static byte[] initVector = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };

    public String decrypt (String encryptedDataBase64, String keyBase64)
    {
       try {
           Security.setProperty("crypto.policy", "unlimited");
           IvParameterSpec ivSpec = new IvParameterSpec(initVector);  // Get the init vector

           // Get the Base64-encoded key
           byte[] key = Base64.decodeBase64(keyBase64.getBytes("UTF-8"));
           Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");  // AES / CBC / PKCS5 padding
           SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
           cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
           byte[] encryptedData = Base64.decodeBase64(encryptedDataBase64.getBytes("UTF-8"));
           byte[] decryptedData = cipher.doFinal(encryptedData);

           return new String(decryptedData);
       }
       catch (Exception e) {
           logger.error("AES256 Decrypt: Decryption exception: "+ e.getMessage());
           return null;
       }
    }
}

现在我们需要将此解密逻辑转换为 Python,因为我们的应用在从服务器请求 index.html 的同时发送标头中的加密数据。我尝试使用 Crypto 解密。它给出了解密后的字符串,但最后还给出了一些额外的字符。

import base64
from Crypto.Cipher import AES

key = base64.b64decode(myKeyBase64)
enc = base64.b64decode(encDataBase64)
ivBase = base64.b64decode('AAAAAAAAAAAAAAAAAAAAAA==');
cipher = AES.new(key, AES.MODE_CBC, ivBase)
cipher.decrypt(enc).decode('utf-8')

它正在正确解密,但最后它给出了一些不在原始字符串中的额外字符,例如 'myText\x06\x06\x06\x06\x06\x06'。 p>

我在阅读了一些堆栈溢出问题后尝试了这个。如果代码有任何错误,谁能告诉我。

【问题讨论】:

  • 在 Java 方面,您使用“...PKCS5PADDING”实例化密码,这意味着明文填充了长度为 16(或 16 的倍数)的字符。添加的字符数是添加的值,因此当添加 6 个字符时,每个填充字符都会获得值 x06,如您的示例所示。解密时(这是您上面的部分),您需要删除最后 6 个 x06 字符。
  • 所有字符串都这样吗?我的意思是对于我加密的任何字符串,如果我通过我的 python 代码解密,它是否总是返回 6 个额外的字符。顺便说一句,我的团队在 Java 端加密时使用 PKCS7 填充。我想我没有正确理解你的评论。能否请您详细说明。

标签: python encryption


【解决方案1】:

要使用 AES 加密字节数组,您确实需要一个 16 字节长的数组 - 然后您可以使用“...NoPadding”。

例如一个 13 个字符长的字符串,然后将字符串转换为一个字节数组,这个数组长 13 个字节。使用 PKCS5,字节数组填充了 3 个字节的值 x03。如果您需要填写 7 个字符,则所有 7 个字节的值都是 x07,缺少 10 个字符会导致 10 个字节的 x0a。

要去除填充,只需读取最后一个字节(例如 x0a = '10')并删除最后 10 个字节以获得原始字符串。

在 Java 端,命名为 PKCS5Padding,(大部分)与 PKCS 相同7Padding(此命名用于其他框架/语言)。

【讨论】:

  • 优秀。谢谢迈克尔。
猜你喜欢
  • 2019-10-01
  • 1970-01-01
  • 2013-09-16
  • 2014-03-18
  • 1970-01-01
  • 1970-01-01
  • 2017-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多