0

我在 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 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

红宝石代码:

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

重击 OpenSSL 命令:

openssl aes-128-cbc -d -in /tmp/file_crypt -out /tmp/file_decrypt_bash -nosalt -iv 00000000000000000000000000000001 -K 7ffb8032dff33aef9aa92e9ac96239d3

编码文件可以在这里下载:http: //pastebin.com/EqHfpxjZ。使用“pbget”(如果有的话)下载文件。否则,复制文本,base 64 解码,lzma 解压。(例如 wget -q -O- "$url" | base64 -d | lzma -d > "$TEMP")。

通过 pbget 或上面的命令获得文件后,您需要进行最后一次 base 64 解码:

base64 -d file_encode_base64 > encrypted_file

为确保您拥有正确的加密文件,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 时得到的结果略有不同?

4

1 回答 1

2

最后,它起作用了!答案其实很简单。您的 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
于 2013-05-24T02:34:44.417 回答