【问题标题】:Why can't I make "OpenSSL with Ruby" and "Command line OpenSSL" interoperable?为什么我不能使“OpenSSL with Ruby”和“命令行 OpenSSL”可互操作?
【发布时间】:2013-01-30 20:49:18
【问题描述】:

在尝试设置可互操作的加密系统时,我在一个简单的“概念验证”中遇到了一个奇怪的情况。

我用 Ruby 编写了以下代码:

  • 从我的文件系统上的虚拟文本文件创建加密文件
  • 解密加密文件
  • 与原文件对比,是否相同

代码如下:

require 'openssl'
require 'base64'

# Read the dummy file
data = File.read("test.txt")

# Create an encrypter
cipher = OpenSSL::Cipher::AES.new(256, :CBC)
cipher.encrypt
key = "somethingreallyreallycomplicated"
cipher.key = key

# Encrypt and save to a file
encrypted = cipher.update(data) + cipher.final
open "encrypted.txt", "w" do |io| io.write Base64.encode64(encrypted) end

# Create a decrypter
decipher = OpenSSL::Cipher::AES.new(256, :CBC)
decipher.decrypt
decipher.key = key

# Decrypt and save to a file
encrypted_data = Base64.decode64(File.read("encrypted.txt"))
plain = decipher.update(encrypted_data) + decipher.final
open "decrypted.txt", "w" do |io| io.write plain end

# Compare original message and decrypted message
puts data == plain #=> true

一切正常,此脚本输出“true”

然后我尝试使用 openssl 命令行通过以下命令解密我的文件:

openssl aes-256-cbc -d -a -in encrypted.txt -k somethingreallyreallycomplicated

但我得到了:bad magic number

怎么会?

【问题讨论】:

    标签: ruby openssl base64 encryption


    【解决方案1】:

    您需要在命令行上使用-K(大写字母)和-iv 选项将键和IV 明确指定为十六进制数字字符串。如果您使用-k(小写),OpenSSL 将使用密钥派生函数从密码中派生密钥和 IV。当 OpenSSL 派生密钥时,它还将使用与您所期望的普通分块 CBC 不兼容的“加盐”密文格式。

    请注意,在您的 Ruby 代码中,您直接使用 ASCII 字符串的前 256 位(32 字节)作为密钥,这几乎肯定不是您想要的安全性问题的实际应用程序。您应该使用(随机生成的)二进制密钥,或使用诸如PBKDF2bcryptscrypt 之类的密钥派生函数从密码派生密钥。

    【讨论】:

    • 感谢您的回答。我曾尝试先生成随机密钥和 ivs,但很难将它们转换为十六进制数字(我在网络上发现关于这种转换的资源出奇地少),因此,在使 openssl 命令行解密时遇到了同样的问题我的 ruby​​ 创建的文件。
    • @DirtyHenry 尝试key.unpack('H*') 将密钥转换为十六进制表示。
    • 只是为了 100% 完成,有什么方法可以从十六进制字符串中再次找到密钥?
    猜你喜欢
    • 2011-05-12
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 1970-01-01
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多