OpenEdge Decryption and DK Generation
During a recent pen testing engagement I was able to access encrypted Card Holder Data (CHD) created by an OpenEdge database. Poor key management procedures were in place allowing me to recover the cleartext and encrypted encryption key, however it did not appear to conform to PBKDF standards for PKE.
Recognizing the opportunity to reverse engineer the encryption function, I took the time to discover that it uses what I will loosely call psuedo-PBKDF logic to create the encryption key. The logic can be summarized as:
P1 = MD5(4000(Cleartext))
P2 = MD5(4000(P1 + Cleartext))
Derived Key = P1 + P2
To simplify this creation in the future I scripted this in Ruby, which can be seen below.
#!/usr/bin/env ruby # Progress OpenEdge Generate-PBE-KEY function in ruby. # - Hardcoded for MD5, 4000 iterations, with a 32-byte key output. require 'openssl' require 'rbkb' puts "Cleartext password:" cleartext = gets.chomp def generate_pbe_key(p) pass = p 4000.times do pass = OpenSSL::Digest::MD5.digest pass end return pass end P1 = generate_pbe_key cleartext P2 = generate_pbe_key (P1+cleartext) DK = P1 + P2 puts "\nMaster Key (base64 encoded):" puts DK.b64 puts "\nMaster Key (hex):" puts DK.hexify
With this key, it is possible to decrypt OpenEdge encrypted data with simple tools:
echo "_ENCRYPTED_VALUE_" | openssl aes-256-cbc -a -d -p -K '_DERIVED_KEY_' -iv ""