user3021683
user3021683

Reputation: 51

Retrieving salt, key, IV in java from encrypted bytes

I'm encrypting a file using openssl with the following command:

openssl enc -aes-128-cbc -in text.txt -out text.enc -pass file:key.bin

where key.bin is a key generated with the command

openssl rand 16 -out: key.bin

For retrieving the salt, key and IV derived from key.bin I'm using:

openssl enc -aes-128-cbc -pass file:key.bin -d -P -in text.enc 

Each time I'm running this command I get the same salt, key and iv.

However, I need to do it in java. Can you please let me know if it is pe possible to retreive these infos in java just passing the encrypted file and the key file?

Upvotes: 0

Views: 1228

Answers (1)

Jim Flood
Jim Flood

Reputation: 8487

You can decrypt the data in Java with just the encrypted file text.enc and the key file key.bin, but you have two problems:

  1. openssl rand can output the value of a null byte or a newline character at any position, which will effectively truncate your password since the contents of -pass file: are read for just the first line of string data.

  2. The default key derivation is not that good. Read this question and answer over at security.stackexchange.

There is more info about the key derivation in this answer. However, here is Ruby code that decrypts the file, which you can translate into Java:

require 'openssl'

enc = File.read('text.enc', :encoding => 'ASCII-8BIT')

# OpenSSL's own file format
salt = enc[8..15]
ciphertext = enc[16..-1]

k = File.read('key.bin', :encoding => 'ASCII-8BIT')
k = k.split(0.chr)[0] # truncate at null byte like openssl would have done
k = k.split("\n")[0] # truncate at newline like openssl would have done

# Key and IV derivation
d = OpenSSL::Digest::MD5.new
d0 = d.digest(k + salt)
d1 = d.digest(d0 + k + salt)

# Compare this to the output when you use the -p argument to openssl enc
puts "salt=#{salt.unpack('H*')[0].upcase}"
puts "key=#{d0.unpack('H*')[0].upcase}"
puts "iv =#{d1.unpack('H*')[0].upcase}"

# Decrypt the ciphertext
cipher = OpenSSL::Cipher.new('AES-128-CBC')
cipher.decrypt
cipher.key = d0
cipher.iv = d1
plaintext = cipher.update(ciphertext) + cipher.final
puts plaintext

Upvotes: 1

Related Questions