为什么可以';“我做什么?”;带Ruby的OpenSSL;及;命令行OpenSSL";可互操作?

为什么可以';“我做什么?”;带Ruby的OpenSSL;及;命令行OpenSSL";可互操作?,ruby,openssl,base64,encryption,Ruby,Openssl,Base64,Encryption,在试图建立一个可互操作的加密系统时,我在一次简单的“概念验证”中遇到了一个奇怪的情况 我用Ruby编写了以下代码: 从我的文件系统上的虚拟文本文件创建加密文件 解密加密的文件 与原始文件进行比较,检查它们是否相同 代码如下: require 'openssl' require 'base64' # Read the dummy file data = File.read("test.txt") # Create an encrypter cipher = OpenSSL::Cipher:

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

我用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
但我得到了:
坏的魔法数字


为什么?

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


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

谢谢您的回答。我曾试图首先生成随机密钥和ivs,但很难将它们转换为十六进制数字(我在web上发现有关此转换的资源少得可怜),因此,在让openssl命令行解密我的ruby创建的文件时也遇到了同样的问题。@DirtyHenry Try
key.unpack('H*'))
将一个键转换为十六进制表示。为了100%完成,如何从十六进制字符串中再次找到该键?