首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AES加密不同结果Java和Python

AES加密不同结果Java和Python
EN

Stack Overflow用户
提问于 2019-10-27 07:55:21
回答 2查看 706关注 0票数 2

我有这个android加密代码作为我的标记,现在我也想用python来实现它,但是它有一些不同的结果。

java

代码语言:javascript
复制
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));

    }
}

python

代码语言:javascript
复制
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结果

代码语言:javascript
复制
-25 -16 84 -36 100 -102 74 -98 -91 -77 100 -96 -86 28 -47 -67

python结果

代码语言:javascript
复制
220 127 95 142 45 102 9 79 170 82 165 2 63 39 196 7

我已经想了好几天了,但不知道问题出在哪里。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-10-27 09:43:36

实际正确的值,即用AES-key MD5加密(填充)块(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
EN

Stack Overflow用户

发布于 2019-10-27 08:31:35

您有不同的代码结构,因此很难比较这些示例。在Python代码中有一个message,但在您的Java代码中没有。

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

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58577518

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档