【问题标题】:AES Encryption Different Result Java And PythonAES加密不同的结果Java和Python
【发布时间】:2019-10-27 07:55:21
【问题描述】:

我有这个 android java AES 加密代码来制作我的令牌,现在我也想在 python 中制作它,但是它有一些不同的结果。

java

private Void encrypt(String password) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, ShortBufferException, BadPaddingException, IllegalBlockSizeException {

    byte[] bytes = password.getBytes(StandardCharsets.UTF_8);

    SecretKeySpec secretKeySpec = new SecretKeySpec(MessageDigest.getInstance("MD5")
    .digest("mysecretkey".getBytes(StandardCharsets.UTF_8)), "AES");

    Cipher instance = Cipher.getInstance("AES/ECB/PKCS5Padding");
    instance.init(1, secretKeySpec);

    byte[] bArr = new byte[instance.getOutputSize(bytes.length)];

    instance.doFinal(bArr, instance.update(bytes,0,bytes.length, bArr, 0));


    for (byte b : bArr){

        Log.d("encrypt", String.valueOf(b));

    }
}

蟒蛇

from Crypto.Cipher import AES

import hashlib


def pad(byte_array):
    BLOCK_SIZE = 16
    pad_len = BLOCK_SIZE - len(byte_array) % BLOCK_SIZE
    return byte_array + (bytes([pad_len]) * pad_len)


def encrypt(key, message):


    byte_array = message.encode("UTF-8")
    panjang = len(message)

    padded = pad(byte_array)

    cipher = AES.new(key.encode("UTF-8"), AES.MODE_ECB)
    encrypted = cipher.encrypt(padded)

    for b in encrypted:
        print(b)





password = "mypassword"

secret_key = "mysecretkey"
hashkey = hashlib.md5(secret_key.encode()).hexdigest()

encrypt(hashkey,password)

java结果

-25 -16 84 -36 100 -102 74 -98 -91 -77 100 -96 -86 28 -47 -67

python 结果

220 127 95 142 45 102 9 79 170 82 165 2 63 39 196 7

我已经解决了几天,但看不出问题出在哪里。

【问题讨论】:

    标签: java python android encryption aes


    【解决方案1】:

    您所追求的实际正确值,即使用 AES 密钥 MD5("mysecretkey") 使用“mypassword”加密(填充)块,这是

    e7 f0 54 dc 64 9a 4a 9e a5 b3 64 a0 aa 1c d1 bd

    被视为十六进制。 (使用标准的openssl 命令行工具生成)

    Java 代码实际上显示了正确的结果:如果上述内容在文件 p.enc 中(就像在我的 PC 上一样),我可以将其以有符号字节显示为

    od -An -t d1 p.enc 然后我得到了

    -25 -16 84 -36 100 -102 74 -98 -91 -77 100 -96 -86 28 -47 -67

    这也是你的代表。

    在 Python 中,您错误地使用 .hexdigest() 而不是 digest()

    hexdigest 生成一个 32 个字符的字符串(带有 ASCII 值,而不是原始二进制),因此您的 AES.new 调用获得一个 256 位密钥,而不是 128 位,结果将是错误的(您将使用 AES-256 )

    您没有指定您使用的 Python 版本。 但是在 Python (2.7) 中,您可以重现正确的结果(假设您从 Crypto 和 hashlib 导入相同)为

    key=hashlib.md5('mysecretkey').digest() plain='mypassword'+ '\006'*6 #manual padding addition for the example aes=AES.new(key, AES.AES_ECB) cipher=aes.encrypt(plain)

    得到上述正确值。

    为了比较而以有符号字节(如 Java 所做的那样)查看它:

    [ord(b)-256 if ord(b)>127 else ord(b) for b in cipher]

    然后结果匹配。

    【讨论】:

      【解决方案2】:

      您有不同的代码结构,这使得比较示例变得困难。在您的 Python 代码中有一个 message,但在您的 Java 代码中没有。

      我的第一个猜测是您应该在 Python 代码中调用 digest 而不是 hexdigesthttps://docs.python.org/2/library/hashlib.html

      您正在执行从哈希到字符串到二进制数据的转换,其中一些使用 UTF-8,但没有。我建议您打印并比较两种语言中传递给加密函数的实际值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-06-06
        • 1970-01-01
        • 2012-03-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多