我正在使用openssl使用以下命令加密文件:
openssl enc -aes-128-cbc -in text.txt -out text.enc -pass file:key.bin
其中key.bin是使用命令
生成的密钥openssl rand 16 -out: key.bin
为了检索从key.bin派生的salt,key和IV,我正在使用:
openssl enc -aes-128-cbc -pass file:key.bin -d -P -in text.enc
每次我运行此命令时,我都会获得相同的盐,密钥和iv。
但是,我需要在java中完成它。 如果可以通过加密文件和密钥文件在java中检索这些信息,请告诉我吗?
答案 0 :(得分:1)
您可以使用加密文件text.enc和密钥文件key.bin解密Java中的数据,但是您有两个问题:
openssl rand可以在任何位置输出空字节或换行符的值,这将有效地截断您的密码,因为只读取第一行字符串数据的-pass file:的内容。 / p>
默认密钥派生不是那么好。在security.stackexchange上阅读this question and answer。
有关this answer中密钥派生的更多信息。但是,这里是解密文件的Ruby代码,您可以将其转换为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