1

I have some data i want to decrypt which is encrypted in AES ECB with PKCS5 padding using java. but i am having hard time decryptiing it. i tried many tutorials and stack overflow ans. but nothing worked for me. help me with this

i am trying like this

    BLOCK_SIZE = 16
    pad = lambda s: s + (BLOCK_SIZE - len(s) % BLOCK_SIZE) * \
                chr(BLOCK_SIZE - len(s) % BLOCK_SIZE)
    unpad = lambda s: s[:-ord(s[len(s) - 1:])]

    def decrypt(key,enc):
        enc = b64decode(enc)
        cipher = AES.new(key.encode("utf8"), AES.MODE_ECB)
        return unpad(cipher.decrypt(enc)).decode('utf8')

    key = '0vlqRTgxr0C]X29C(}{M\\&TZErb$1!f{'
    enc = 'T3cPMizpZj63+iVwXvlFUnD8Hld5XN4h3v3Ncd8YuIk='

but i am getting only empty string back

Neeraj joon
  • 11
  • 1
  • 4
  • I think `s[:-ord(s[len(s) - 1:])]` should be `s[:-ord(s[-1])]` (without the colon). Perhaps a typo? – Evan Su Jan 02 '22 at 17:17
  • Also, that is PKCS7 padding, not PKCS5. – Evan Su Jan 02 '22 at 17:45
  • 1
    @EvanSu: since 2017 they're the same; PKCS5v2.1 rfc8018 adds AES and RC5(128) with the padding from CMS rfc5652 which is the current PKCS7. And Java -- or more exactly the defacto standard cryptoproviders for Java from Sun-now-Oracle-and-OpenJDK -- has since ~2000 used the name PKCS5Padding for both. – dave_thompson_085 Jan 02 '22 at 19:32
  • @dave_thompson_085, thanks for the new knowledge :) I don't use Java so I didn't know. – Evan Su Jan 02 '22 at 22:43
  • 1
    It may be that your key is maybe incorrectly translated, it already contains a double backslash. Keys should be binary, they should not consist of characters. – Maarten Bodewes Jan 03 '22 at 09:04

1 Answers1

2

It looks like you are using the PyCrypto/PyCryptoDome package for encryption. Instead of writing your own padding function, it's easier to use the built-in one. Here's the example from the docs:

from Crypto.Util.Padding import pad, unpad
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

data = b'Unaligned'   # 9 bytes
key = get_random_bytes(32)
iv = get_random_bytes(16)

cipher1 = AES.new(key, AES.MODE_CBC, iv)
ct = cipher1.encrypt(pad(data, 16))

cipher2 = AES.new(key, AES.MODE_CBC, iv)
pt = unpad(cipher2.decrypt(ct), 16)
assert(data == pt)

So in your case, you can get rid of the padding functions and simply rewrite the encrypt and decrypt functions to use PyCryptoDome's padding utils. I've done that for you here with two functions, encrypt and decrypt.

from Crypto.Util.Padding import pad, unpad
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from base64 import b64encode,b64decode

key = get_random_bytes(32)
iv = get_random_bytes(16)

def encrypt(plaintext,key):
    cipher = AES.new(key,AES.MODE_CBC,iv)
    return b64encode(cipher.encrypt(pad(plaintext.encode(),16))).decode()
def decrypt(ciphertext,key):
    cipher = AES.new(key,AES.MODE_CBC,iv)
    return unpad(cipher.decrypt(b64decode(ciphertext.encode())),16).decode()

And testing it:

>>> encrypt("hello",key)
'aekD8rXrimLT12hFWg22ww=='
>>> decrypt('aekD8rXrimLT12hFWg22ww==',key)
'hello'

Note that I used CBC mode because ECB mode is insecure and shouldn't ever be used. Even CBC has weaknesses, and I would recommend you use CTR mode and an HMAC, or GCM mode which will take care of everything for you.

Evan Su
  • 136
  • 3
  • In the first part, the padding is applied by who? – kelalaka Jan 02 '22 at 22:24
  • OP was using his own padding function which looks correct, but I suggested he use a standard implementation by the same cryptography library for reliability and cleanliness. – Evan Su Jan 02 '22 at 22:42
  • I think it is better to use [non-library correct unpadding on this part](https://stackoverflow.com/a/54166852/1820553) – kelalaka Jan 02 '22 at 22:47
  • 1
    I guess it would depend on what library OP is using. The old PyCrypto doesn't have padding functions, but the newer and better-maintained PyCryptodome does and is a drop-in replacement. So if OP is using PyCrypto and doesn't want to use PyCryptodome, then you would be correct. Thanks for pointing it out. – Evan Su Jan 02 '22 at 22:50
  • i am using PyCryptodome. but the example u have given are for CBC mode.my data is already encrypted in ECB. that i want to decrypt. – Neeraj joon Jan 03 '22 at 05:58
  • 1
    The above functions are still correct for it. It defaults to PKCS#7 padding, [which is identical to Java's PKCS#5 padding](https://crypto.stackexchange.com/q/9043/1172). However, it may be that your key / ciphertext combination is incorrect, which would result in invalid padding. The problem with your own code is that it hides any unpadding errors, which I would claim is incorrect. – Maarten Bodewes Jan 03 '22 at 08:49