如何从 encrypted_strings 中提取加密方法生成的 IV 向量
How to extract the IV vector generated by encrypt method from encrypted_strings
我无法从 encrypted_strings
库中为我提供的特定密码提取使用 encrypt
方法生成的 IV。从文档中,我看到此方法使用 C 库基于密码生成密钥和 iv,该库调用与 openssl 相同的方法来生成密钥和 iv:EVP_BytesToKey.
我想做的是能够为我指定的任何密码打印 IV,这样我就可以将加密移植到另一种语言。
你能想出从密码中 extract/print 这个 IV 向量的方法吗?
这些是该库使用的算法、模式和填充的详细信息:
- 算法:DES-EDE3
- 模式:CBC
- 填充:PKCS5
下面的 ruby 脚本打印出加密消息,但不知道使用了哪个 iv。
#!/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}"
我尝试使用 openssl
,因为它允许我打印使用 [=16=] 选项生成的 iv 和密钥,但它使用 PKCS7
填充而不是 PKCS5
。因此,如果我 运行 下面的命令,不会打印与上面的 ruby 代码相同的加密字符串。
echo -n 'Whackabad' | openssl enc -des-ede3-cbc -nosalt -a -k bAJLyifeUJUBFWdHzVbykfDmPHtLKLMzViHW9aHGmyTLD8hGYZ
注意:
-a:base64 编码,-k:密码和回显 -n:从字符串中删除新行,因此它的大小与字符串中的 ruby 完全相同。
如果我添加 -nopad
选项,我不知道如何填充输出以获得完全相同的加密结果。
如有任何帮助,我们将不胜感激
PKCS7 padding 与PKCS5基本相同。你在命令行上得到不同结果的原因是它只使用一个散列迭代,其中 encrypted_strings
does 2048 iterations by default.
使用的函数
使用的函数,EVP_BytesToKey
is described in the OpenSSL wiki,其中包含算法的详细信息。在 Ruby 中重现它可能看起来像这样(使用 MD5 和 2048 次迭代):
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]
您可以使用这些值来解密代码的结果(先添加 require 'base64'
):
# 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
库中为我提供的特定密码提取使用 encrypt
方法生成的 IV。从文档中,我看到此方法使用 C 库基于密码生成密钥和 iv,该库调用与 openssl 相同的方法来生成密钥和 iv:EVP_BytesToKey.
我想做的是能够为我指定的任何密码打印 IV,这样我就可以将加密移植到另一种语言。
你能想出从密码中 extract/print 这个 IV 向量的方法吗?
这些是该库使用的算法、模式和填充的详细信息:
- 算法:DES-EDE3
- 模式:CBC
- 填充:PKCS5
下面的 ruby 脚本打印出加密消息,但不知道使用了哪个 iv。
#!/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}"
我尝试使用 openssl
,因为它允许我打印使用 [=16=] 选项生成的 iv 和密钥,但它使用 PKCS7
填充而不是 PKCS5
。因此,如果我 运行 下面的命令,不会打印与上面的 ruby 代码相同的加密字符串。
echo -n 'Whackabad' | openssl enc -des-ede3-cbc -nosalt -a -k bAJLyifeUJUBFWdHzVbykfDmPHtLKLMzViHW9aHGmyTLD8hGYZ
注意: -a:base64 编码,-k:密码和回显 -n:从字符串中删除新行,因此它的大小与字符串中的 ruby 完全相同。
如果我添加 -nopad
选项,我不知道如何填充输出以获得完全相同的加密结果。
如有任何帮助,我们将不胜感激
PKCS7 padding 与PKCS5基本相同。你在命令行上得到不同结果的原因是它只使用一个散列迭代,其中 encrypted_strings
does 2048 iterations by default.
使用的函数,EVP_BytesToKey
is described in the OpenSSL wiki,其中包含算法的详细信息。在 Ruby 中重现它可能看起来像这样(使用 MD5 和 2048 次迭代):
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]
您可以使用这些值来解密代码的结果(先添加 require 'base64'
):
# 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"