i.crave.beer – The online home of Joshua Skorich

13th April 2015

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 ""

Available at https://github.com/joshuaskorich/pentest-tools/blob/master/openedge.rb