0

I'm writing a test script which I'm using to try and decrypt an encrypted string I have the key to. However, while the code somewhat runs, it is not printing the full string/value that I am expecting (and know the result for).

For example, rather than returning ThisIsTheStringThatWorks it is returning atWorks

Here is the code:

import base64
import hashlib
from Crypto.Cipher import AES

BLOCK_SIZE = 16
unpad = lambda s : s[0:-s[-1]]

def decrypt(enc, secret_key):
    private_key = hashlib.sha256(secret_key.encode('utf-8')).digest()
    enc = base64.b64decode(enc)
    iv = enc[:BLOCK_SIZE]
    cipher = AES.new(private_key, AES.MODE_CBC, iv)
    return unpad(cipher.decrypt(enc[BLOCK_SIZE:]))

decrypted = decrypt(mail_pass, secret_key)
print(bytes.decode(decrypted))

Any help would be greatly appreciated. Thanks in advance.

MrY
  • 13
  • 3
  • 1
    How long is your ciphertext? Can you post the encryption code? – mat Sep 12 '19 at 12:24
  • SHA-256 is not a proper Key Derivation Function:https://pycryptodome.readthedocs.io/en/latest/src/protocol/kdf.html The CBC mode is considered obsolete. You should use a AEAD mode: https://pycryptodome.readthedocs.io/en/latest/src/cipher/modern.html – Erwan Legrand Sep 12 '19 at 16:52
  • @mat Regarding the length of the cipher text, it can be deducted from the information provided by the OP. See my answer. A copy of the encryption code would indeed be useful! – Erwan Legrand Sep 13 '19 at 10:11
  • The provided code sample does not run, since `secret_key` is not defined. Are `passw` and `secret_key` supposed to be the same? – Erwan Legrand Sep 13 '19 at 10:13
  • `secret_key` is a variable that contains the actual key. I reformatted my original code to make it clear that `passw` is the same as `secret_key` to avoid confusion. `mail_pass` is the encrypted text while `secret_key` is the key required to decrypt. – MrY Sep 13 '19 at 17:34

1 Answers1

0

You have not included the IV in the encrypted message. You are using the first encrypted block as the IV during decryption and as a result the data encrypted in the first block is lost.

You must concatenate the IV and the cipher text in the encryption routine if you want this decryption routine to work:

enc = iv + cipher.encrypt(clear)
Erwan Legrand
  • 4,148
  • 26
  • 26
  • Thanks for the response, Erwan. Using my code, would you be able to provide an example of your explanation so that I can better understand the direction you're giving? – MrY Sep 12 '19 at 18:27
  • @MrY I have added a code example, but since you do not provide the encryption routine, this might not match your actual code. – Erwan Legrand Sep 13 '19 at 10:02
  • @MrY Also, since it is obvious you do not know enough about cryptography, I think you should not use PyCryptodome or worse, the discontinued PyCrypto. Cryptography is hard. I suggest you use the foolproof pyNaCl instead: https://pynacl.readthedocs.io/en/stable/secret/ – Erwan Legrand Sep 13 '19 at 10:06