如何使用Ruby对使用openssl命令行实用程序加密的明文进行解密,该实用程序使用密码而不使用盐?

如何使用Ruby对使用openssl命令行实用程序加密的明文进行解密,该实用程序使用密码而不使用盐?,ruby,openssl,Ruby,Openssl,我使用openssl命令行实用程序使用密码加密了一些明文: echo -n "foo" | openssl enc -e -base64 -rc4 -nosalt -pass pass:secretkey echo -n "foo" | openssl enc -e -base64 -rc4 -nosalt -pass pass:secretkey 这将返回: ryW2 key=610A2EE688CDA9E724885E23CD2CFDEE ryW

我使用
openssl
命令行实用程序使用密码加密了一些明文:

echo -n "foo" | openssl enc -e -base64 -rc4 -nosalt -pass pass:secretkey
echo -n "foo" | openssl enc -e -base64 -rc4 -nosalt -pass pass:secretkey
这将返回:

ryW2
key=610A2EE688CDA9E724885E23CD2CFDEE
ryW2
foo
ryW2

如何使用Ruby解密此值?

以下是需要输入的命令,以将字符串
foo
加密为某种密文:

echo -n "foo" | openssl enc -e -base64 -rc4 -nosalt -pass pass:secretkey -p
这将返回:

ryW2
key=610A2EE688CDA9E724885E23CD2CFDEE
ryW2
foo
ryW2
ryW2
是您的base64编码密文

我们添加了
-p
,因此可以看到用于加密的密钥

-p
是必需的,因为OpenSSL使用内部函数
EVP_BytesToKey
将密码短语转换为密钥,并且没有等效的Ruby方法来实现这一点。因此,在加密或解密时,您必须直接在Ruby中使用该密钥值,而不是密码短语

解密也同样简单:

echo "ryW2" | openssl enc -d -base64 -rc4 -nosalt -pass pass:secretkey
这将返回:

ryW2
key=610A2EE688CDA9E724885E23CD2CFDEE
ryW2
foo
ryW2
考虑到所有这些,下面是如何使用Ruby加密此字符串以获得相同的值:

require 'openssl'
require 'base64'

plaintext = 'foo'
cipher = OpenSSL::Cipher.new('rc4')
cipher.encrypt
# Use the key that was generated by EVP_BytesToKey
key = '610A2EE688CDA9E724885E23CD2CFDEE'
# Convert the key to a byte string
key_bytes = key.scan(/../).map { |x| x.hex.chr }.join
cipher.key = key_bytes
ciphertext = cipher.update(plaintext) + cipher.final
base64 = Base64.strict_encode64(ciphertext)
这将在命令行上返回与OpenSSL相同的值:

ryW2
解密相当简单:

decipher = OpenSSL::Cipher.new('rc4')
decipher.decrypt
decipher.key = key_bytes
decrypted = decipher.update(ciphertext) + decipher.final
这将返回原始纯文本:

foo
foo
归根结底,只要您知道给定的
pass
EVP\u BytesToKey
将返回什么,加密和解密就相当简单。您可以在这里阅读更多关于EVP_BytesToKey的信息:


最后在Ruby中引用上述内容

编码 解码
我不高兴Ruby中没有内置的方法来实现这一点。解决这个问题是一个功能性的解决方法,但它需要一些我并不热衷的耗时步骤。所以我写了一个叫做“我会帮你的”的gem

首先安装gem:

gem install evp_bytes_to_key
然后生成密文:

echo -n "foo" | openssl enc -e -base64 -rc4 -nosalt -pass pass:secretkey -p
这将返回:

ryW2
key=610A2EE688CDA9E724885E23CD2CFDEE
ryW2
foo
ryW2
然后在Ruby中解密:

require 'evp_bytes_to_key'
require 'openssl'
require 'base64'

decipher = OpenSSL::Cipher.new('rc4')
decipher.decrypt
decipher.key = EvpBytesToKey::Key.new('secretkey', nil, 128, 0).key
ciphertext = Base64.strict_decode64('ryW2')
plaintext = decipher.update(ciphertext) + decipher.final
这将返回原始纯文本:

foo
foo

更多使用此gem的示例可以在中找到。

感谢它确实有效,我在部分关键字节中感到困惑