Ruby openssl lib - 为什么AES-256-CBC解密会在没有正确IV的情况下提供可读数据?

时间:2012-12-13 22:25:32

标签: ruby openssl aes

给出以下脚本

require "openssl"
require "securerandom"

key = SecureRandom.random_bytes(32)
iv = SecureRandom.random_bytes(16)

aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC")
aes.encrypt
aes.key = key
aes.iv = iv

crypted = aes.update("a"*50)+aes.final

aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC")
aes.decrypt
aes.key = key
aes.iv = iv

puts aes.update(crypted)+aes.final

aes = OpenSSL::Cipher::Cipher.new("AES-256-CBC")
aes.decrypt
aes.key = key

puts aes.update(crypted)+aes.final

我得到以下输出(例如):

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
���y��f{�K~:y��aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

我是否需要自己执行这些CBC风格的XOR操作,块大小关怀等?我找不到任何简单地调用更新函数传递应解密的字符串的示例。我已经尝试将.dup添加到所有字符串分配以防止就地编辑问题。这是怎么回事?

环境:ruby 1.9.3p194(2012-04-20修订版35410)[x86_64-linux]

1 个答案:

答案 0 :(得分:4)

IV的目的是通过分析包含相同数据的多条消息来防止发现密钥。如果您有密钥,则无意隐藏信息。没有正确的IV,密文的第一个块将是不正确的,但后续的块将正确解密,如您所发现的那样。 IV保护密钥,而不是数据。

如果你通过openssl命令行工具执行类似的加密,你会得到同样的东西(这里我用8个空格字符替换加密密文中嵌入的8字节IV):

echo "Ruby openssl lib - Why does AES-256-CBC decrypting gives readable data without the correct IV?" | \
openssl enc -aes-256-cbc -salt -pass pass:password | \
perl -pi -e "s/^(.{8})(.{8})/\1        /" | \
openssl enc -d -aes-256-cbc -salt -pass pass:password

▒▒▒▒▒▒t▒8q▒g] -▒▒▒▒▒▒7<s AES-256-CBC decrypting gives readable data without the correct IV?