从加密字节中检索java中的salt,key,IV

时间:2014-05-01 10:15:23

标签: java key salt

我正在使用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中检索这些信息,请告诉我吗?

1 个答案:

答案 0 :(得分:1)

您可以使用加密文件text.enc和密钥文件key.bin解密Java中的数据,但是您有两个问题:

  1. openssl rand可以在任何位置输出空字节或换行符的值,这将有效地截断您的密码,因为只读取第一行字符串数据的-pass file:的内容。 / p>

  2. 默认密钥派生不是那么好。在security.stackexchange上阅读this question and answer

  3. 有关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