Reputation: 21
I'm attempting to migrate some encrypted data from an ancient mysql database system to a newer one.
The old system simply wrapped openssl to perform encryption and decryption of some of the table data, using an old version of openssl that used 3des with an md5 digest and base64.
I've managed to get a more modern openssl to decrypt the data using :
openssl enc -des3 -md md5 -a -A -pass pass:<PASSPHRASE> -d
However, if it's possible I'd like to implement the migration without having to make system calls to openssl to convert the data to a more modern and secure encryption standard.
I know I can reverse the base64 encoding with:
import base64
b64_decoded = base64.b64decode(b64_encoded)
which gives me a byte string along the lines of:
b'Salted__\xcb\\\x92|\xa60\xab\xb4\x93\xbe\xff\xf2"W\xb7:\xc0\xfb\t\xc2\xba\x11\x00\xd0\xbd$--sQzJ\x10\xce0\xc78=hX\x95o\x82T\xe1\xc3\x9d\x14Qm-9`\x9c>zbV\xa3\xb5h\xc5w_\x93\xbc\x05\x8f?\x0e\xe7\xdaSuX?\xddwn\x7f\xb5\xaf[\x0b\x02\x80\xb0-N\x03^\x1c\xa5\xd6?6Q\x10.\xd5\xe7g\x7fZ!H\x14\xc0\xbb\xf4\xe6P<\xed~\xbc\xdaA\xd7\xe5\xc2I\xe8K\x04\xfe\xc5\xab2#>)\xc80 ... '
Does anyone know enough about the inner workings of openssl's key and iv derivation to be able to tell me how I might derive the key, iv etc from the passphrase and decoded data to be able to pass the right data to something like the Oscrypto or Cryptography library 3des functions?
Cheers,
Tek
Upvotes: 1
Views: 694
Reputation: 21
Finally stumbled on the right search and found the answer I was looking for eventually here in a post by mti2935
The following code will give the key and iv:
import base64
import hashlib
b64_encoded_ciphertext = "<BASE64 encoded ciphertext>"
passphrase = "<passphrase>"
# base64 decode to give the raw bytes of the ciphertext
ciphertext = base64.b64decode(b64_encoded_ciphertext)
# passphrase must be raw bytes too
passphrase = passphrase.encode('utf-8')
# the 8 bytes following "Salted__" in the ciphertext are the salt
salt = ciphertext[8:16]
# we hash a couple of times
round1 = hashlib.md5(passphrase + salt).digest()
round2 = hashlib.md5(round1 + passphrase + salt).digest()
# sum the two rounds
final_hash = round1 + round2
# the key is the first 24 bytes of that final hash
key = final_hash[0:24]
# and the iv is the remaining 8
iv = final_hash[24:]
Upvotes: 1