2

I have this android java AES encryption code that make my token, now i want to make it in python too, but some how it has different result.

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

    }
}

python

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 result

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

python result

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

i've been figuring out this for days but cant see where the problem is.

2 Answers 2

2

The actually correct values your going for, i.e. encrypting a (padded) block with "mypassword" with the AES-key MD5("mysecretkey"), this is

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

viewed as hex. (produced with the standard openssl command line tool)

The Java code actually shows the correct result: if the above is in a file p.enc (as it is on my PC), I can display it in signed bytes as

od -An -t d1 p.enc and then I get

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

which is your representation as well.

In Python you wrongly use .hexdigest() instead of digest().

hexdigest produces a 32 character string (with ASCII values, not raw binary) so your AES.new call gets a 256-bits key, not 128 bits and the result will be wrong (you'll use AES-256)

You're not specifying what version of Python you're using. But in Python (2.7) you can reproduce the correct result (assuming your same imports from Crypto and hashlib) as

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)

which gets the abovementioned correct value.

To view it in signed bytes (as Java does) for comparison's sake:

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

And the results then match up.

Sign up to request clarification or add additional context in comments.

Comments

2

You have different code structure, that makes it difficult to compare the examples. There's a message in your Python code, but not in your Java code.

My first guess is that you should be calling digest instead of hexdigest in the Python code. https://docs.python.org/2/library/hashlib.html

You're doing conversions from hashes to strings to binary data, some of the latter with UTF-8, but one without. I recommend that you print and compare the actual values that you're passing to the encryption function in both languages.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.