为什么Ruby openssl aes 128 cbc的前16个字节是错误的?
我使用Ruby 1.8.7中的OpenSSL和Bash中的OpenSSL对文件进行解码,但是使用Ruby代码,解密文件中的前16个字节是错误的 这是我用Ruby得到的结果为什么Ruby openssl aes 128 cbc的前16个字节是错误的?,ruby,openssl,Ruby,Openssl,我使用Ruby 1.8.7中的OpenSSL和Bash中的OpenSSL对文件进行解码,但是使用Ruby代码,解密文件中的前16个字节是错误的 这是我用Ruby得到的结果 cf e8 cf d1 12 e2 75 48 59 56 30 30 7d 7d 30 1b | wrong bytes 00 00 00 08 00 0c 01 1a 00 05 00 00 00 01 00 00 | good bytes 01 46 01 1b 00 05 00 00 00 01 00 00 01
cf e8 cf d1 12 e2 75 48 59 56 30 30 7d 7d 30 1b | wrong bytes
00 00 00 08 00 0c 01 1a 00 05 00 00 00 01 00 00 | good bytes
01 46 01 1b 00 05 00 00 00 01 00 00 01 4e 01 28 | good bytes
********************good bytes****************** | good bytes
这就是我在Bash中使用OpenSSL得到的结果
ff d8 ff e1 22 d2 45 78 69 66 00 00 4d 4d 00 2a | correct bytes
00 00 00 08 00 0c 01 1a 00 05 00 00 00 01 00 00 | same bytes as in Ruby
01 46 01 1b 00 05 00 00 00 01 00 00 01 4e 01 28 | same bytes as in Ruby
*******************a lot of bytes*************** | same bytes as in Ruby
Ruby代码:
require 'openssl'
c = OpenSSL::Cipher::Cipher.new("aes-128-cbc")
c.decrypt
c.key = "\177\373\2002\337\363:\357\232\251.\232\311b9\323"
c.iv = "00000000000000000000000000000001"
data = File.read("/tmp/file_crypt")
d = c.update(data)
d << c.final
file = File.open("/tmp/file_decrypt_ruby", "w")
file.write(d)
file.close
可在此处下载编码文件:。使用“pbget”(如果有的话)下载文件。否则,复制文本,对其进行base64解码,然后lzma对其进行解压缩。(例如wget-q-O-“$url”| base64-d | lzma-d>“$TEMP”)
一旦通过pbget或上述命令获得文件,您将需要执行最后一次base 64解码:
base64-d文件\u编码\u base64>加密\u文件
为确保您拥有正确的加密文件,MD5哈希为:30b8f5e7d700c108cd9815c00ca1de2d
如果使用Bash版本的OpenSSL对该文件进行解码,则会获得JPG格式的图片
但是,如果使用Ruby版本,则会获得一个与picture.jpg不同的数据文件,其长度为前16个字节
作为参考,这是我首先用来加密文件的命令:
openssl aes-128-cbc -e -in picture.jpg -out enc_file -nosalt -iv 00000000000000000000000000000001 -K 7ffb8032dff33aef9aa92e9ac96239d3
有人能解释一下为什么我可以在Bash中用OpenSSL对其进行解码,但在使用Ruby时得到的结果略有不同吗?最后,它成功了!答案其实很简单。您的IV需要在Ruby代码中转换为二进制,类似于您转换密钥的方式。我在一篇评论中找到了转换代码和解释 请尝试以下代码:
require 'openssl'
cipher = OpenSSL::Cipher::Cipher.new("aes-128-cbc")
cipher.decrypt
cipher.key = "7ffb8032dff33aef9aa92e9ac96239d3".unpack('a2'*16).map{|x| x.hex}.pack('c'*16)
cipher.iv = "00000000000000000000000000000001".unpack('a2'*16).map{|x| x.hex}.pack('c'*16)
data = File.read("/tmp/file_crypt")
decrypted = cipher.update(data) + cipher.final
file = File.open("/tmp/file_decrypt_ruby", "w")
file.write(decrypted)
file.close
谢谢你,请看我的编辑。非常感谢你。请查看我的新编辑。谢谢gtrig我没有这个MD5哈希。请查看我的新编辑。好的,我现在有正确的文件了。对于其他研究这个问题的人来说,pbget实际上做了一些事情。首先它对URL执行wget,然后执行base64解码,然后执行lzma解压缩。例如wget-q-O-“$url”| base64-d | lzma-d>“$TEMP”。因此,如果您抓取pastebin上的文本,您需要对其进行base64解码,lzma解压缩,然后再次对其进行base64解码,以获得问题中提到的加密文件。听起来像是你用pbput上传了加密文件。在这种情况下,在使用pbput之前不需要对其进行base64编码。pbput已经为您完成了。我现在可以复制您看到的内容。关于解密文件的前15个字节,一个有趣的事情是,它们的每个字节都有0x10或0x30的完全不同。当前15个中存在重复字节时,另一个中存在相应的重复字节。我不知道这是巧合还是问题所在的线索。
require 'openssl'
cipher = OpenSSL::Cipher::Cipher.new("aes-128-cbc")
cipher.decrypt
cipher.key = "7ffb8032dff33aef9aa92e9ac96239d3".unpack('a2'*16).map{|x| x.hex}.pack('c'*16)
cipher.iv = "00000000000000000000000000000001".unpack('a2'*16).map{|x| x.hex}.pack('c'*16)
data = File.read("/tmp/file_crypt")
decrypted = cipher.update(data) + cipher.final
file = File.open("/tmp/file_decrypt_ruby", "w")
file.write(decrypted)
file.close