I've spent the night reversing the implementation of the 'Basic Text Encryptor' from Jasypt [1]. The algorithm is defined in documentation as 'PBEWithMD5AndDES'.
The implementation is this:
- A random 64-bit salt is generated
- The secret is generated as
secret = password + salt
for i in range(0, 1000):
secret = md5(secret)
- The first 8 bytes of the secret are then used as the DES passphrase, and the last 8 bytes of the secret are used as the IV, and used to encrypt data with DES-CBC.
Given this, am I correct in thinking the total keyspace for the implementation is 120 bits (56+64)?
I have written a proof of concept reversal in python, but I'm interested in calculating how long it would take to brute force a real key. So far I've been unable to induce hashcat into decrypting something encrypted with this algorithm, and I'm unsure if it even can.
My questions are:
- Is the keyspace really 120 bits?
- Am I missing something or is hashcat not capable of cracking this?
- Can other tools crack it?
- Is it even possible to deduce correct outputs without making assumptions on expected output (eg all output must be ASCII data, or match a file header)
Edit: To reduce any confusion, my decryptor is as follows
import base64
import hashlib
from Crypto.Cipher import DES
passphrase = "123456" # Key used to encrypt
# Salt randomly generated at encrypt-time, and stored at
# the beginning of the encrypted data:
salt = base64.b64decode("vqmy2fiCipU=")
enc_b64 = "vqmy2fiCipVBIhiAzDfvTL0301DLgTqd"
enc_data = base64.b64decode(enc_b64)
if (salt != enc_data[0:8]):
raise Exception("Salt does not match enc_data salt")
enc_data = enc_data[8:]
m = hashlib.md5()
m.update(passphrase.encode())
m.update(salt)
result = m.digest()
for i in range(1, 1000):
m = hashlib.md5()
m.update(result)
result = m.digest()
# value of result is: md5("123456" + salt) iterated 1,000 times.
key = result[:8]
iv = result[8:16]
des = DES.new(key, DES.MODE_CBC, iv)
print(des.decrypt(enc_data).decode())
# > Hello World
[1] http://www.jasypt.org/api/jasypt/1.8/org/jasypt/util/text/BasicTextEncryptor.html