如何从encrypted_strings中提取加密方法生成的IV向量 [英] How to extract the IV vector generated by encrypt method from encrypted_strings

查看:363
本文介绍了如何从encrypted_strings中提取加密方法生成的IV向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 encrypt 方法从 encrypted_strings 库中提取出特定密码的问题,我遇到麻烦我提供从文档中,我看到这个方法生成一个密钥,并使用一个密码,使用C库调用与openssl相同的方法生成密钥,iv:EVP_BytesToKey。



我想要做的是能够为我指定的任何密码打印IV,所以我可以将加密移植到另一种语言。



你能想想从密码中提取/打印此IV向量的任何方法?



这些是本库使用的算法,模式和填充的细节:




  • ALGO:DES-EDE3

  • 模式:CBC

  • PADDING:PKCS5



下面的ruby脚本打印出加密的消息,但没有使用iv的线索。

 #!/ usr / bin / ruby​​ 
require'encrypted_strings'

data ='Whackabad'
password = bAJLyifeUJUBFWdHzVbykfDmPHtLKLMzViHW9aHGmyTLD8hGYZ'

encrypted_data = data.encrypt(:symmetric,:password =>密码)
printf数据:#{data} \\\

printf加密数据:#{encrypted_data}

我试图使用 openssl ,因为它允许我打印使用 -p 选项,但它使用一个 PKCS7 填充而不是 PKCS5 。所以如果我运行下面的命令,不打印与上面的ruby代码相同的加密字符串。

  echo -n' Whackabad'| openssl enc -des-ede3-cbc -nosalt -a -k bAJLyifeUJUBFWdHzVbykfDmPHtLKLMzViHW9aHGmyTLD8hGYZ 

注意:
-a:base64 encode,-k:password和echo -n:从字符串中删除新行,因此与字符串中的ruby的大小完全相同。



如果我添加 -nopad 选项,我不知道如何填充输出以获得完全相同的加密结果。



任何帮助将不胜感激

解决方案

PKCS7填充基本上和PKCS5一样。在命令行上获得不同结果的原因是它只使用单个散列迭代,其中使用 encrypted_strings 默认执行2048次迭代



使用的功能, EVP_BytesToKey 在OpenSSL维基中有描述,其中包括该算法的详细信息。在Ruby中重现它可能看起来像这样(使用MD5和2048迭代):

  def hash(d,count)
count.times do
d = OpenSSL :: Digest.digest('md5',d)
end
d
end

password ='bAJLyifeUJUBFWdHzVbykfDmPHtLKLMzViHW9aHGmyTLD8hGYZ '

bytes =''
last =''

#对于des-ede3-cbc,24字节键+ 8字节IV = 32字节。
while bytes.length< 32
last = hash(last + password,2048)
bytes<<最后
end

key = bytes [0 ... 24]
iv = bytes [24 ..- 1]
/ pre>

您可以使用这些值解密代码的结果(首先添加 require'base64'

 #这是你的代码的结果:
encrypted_data =AEsDXVcgh2jsTjlDgh + REg ==

#enrypted_strings生成base64编码结果,所以我们先解码
encrypted_data = Base64.decode64(encrypted_data)

cipher = OpenSSL :: Cipher.new('des-ede3- cbc')
cipher.decrypt
cipher.key = key
cipher.iv = iv

plain = cipher.update(encrypted_data)+ cipher.final

put plain#=> Whackabad


I'm having troubles to extract the IV generated with the encrypt method from encrypted_strings library for a specific password I provide. From the documentation, I see that this method generates a key and iv based on a password using a C library that calls the same method as openssl to generate the key and iv: EVP_BytesToKey.

What I'm trying to do is to be able to print the IV for any password I specify so I can port the encryption to another language.

Can you think of any method to extract/print this IV vector from a password?

These are the details of the algorithm, mode and padding this library uses:

  • ALGO: DES-EDE3
  • MODE: CBC
  • PADDING: PKCS5

The ruby script below prints out the encrypted message but no clue which iv was used.

#!/usr/bin/ruby
require 'encrypted_strings'

data = 'Whackabad'
password = 'bAJLyifeUJUBFWdHzVbykfDmPHtLKLMzViHW9aHGmyTLD8hGYZ'

encrypted_data = data.encrypt(:symmetric, :password => password)
printf "Data: #{data}\n"
printf "Encrypted Data: #{encrypted_data}"

I tried to use openssl as it allows me to print the iv and key generated using -p option but it uses a PKCS7 padding instead of PKCS5. So if I run the command below, doesn't print the same encrypted string as the ruby code above.

echo -n 'Whackabad' | openssl enc -des-ede3-cbc -nosalt -a -k bAJLyifeUJUBFWdHzVbykfDmPHtLKLMzViHW9aHGmyTLD8hGYZ

NOTE: -a: base64 encode, -k: password, and echo -n: removes the new line from the string so its exactly the same size as the ruby in string.

If I add -nopad option, I don't know how to pad the output to get exactly the same encrypted result.

Any help would be much appreciated

解决方案

PKCS7 padding is basically the same as PKCS5. The reason you get a different result on the command line is that it only uses a single hash iteration, where the function used by encrypted_strings does 2048 iterations by default.

The function used, EVP_BytesToKey is described in the OpenSSL wiki, which include details of the algorithm. Reproducing it in Ruby might look something like this (using MD5 and 2048 iterations):

def hash(d, count)
  count.times do
    d = OpenSSL::Digest.digest('md5', d)
  end
  d
end

password = 'bAJLyifeUJUBFWdHzVbykfDmPHtLKLMzViHW9aHGmyTLD8hGYZ'

bytes = ''
last = ''

# For des-ede3-cbc, 24 byte key + 8 byte IV = 32 bytes.
while bytes.length < 32
  last = hash(last + password, 2048)
  bytes << last
end

key = bytes[0...24]
iv = bytes[24..-1]

You can use these values to decrypt the result of your code (add require 'base64' first):

# This is the result of your code:
encrypted_data = "AEsDXVcgh2jsTjlDgh+REg=="

# enrypted_strings produces base64 encoded results, so we decode first
encrypted_data = Base64.decode64(encrypted_data)

cipher = OpenSSL::Cipher.new('des-ede3-cbc')
cipher.decrypt
cipher.key = key
cipher.iv = iv

plain = cipher.update(encrypted_data) + cipher.final

puts plain #=> "Whackabad"

这篇关于如何从encrypted_strings中提取加密方法生成的IV向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆