【发布时间】:2020-07-10 11:29:50
【问题描述】:
我使用openssl 命令行实用程序使用密码加密了一些明文:
echo -n "foo" | openssl enc -e -base64 -rc4 -nosalt -pass pass:secretkey
这会返回:
ryW2
如何使用 Ruby 解密这个值?
【问题讨论】:
我使用openssl 命令行实用程序使用密码加密了一些明文:
echo -n "foo" | openssl enc -e -base64 -rc4 -nosalt -pass pass:secretkey
这会返回:
ryW2
如何使用 Ruby 解密这个值?
【问题讨论】:
最后在Ruby中参考了Above
def encrypt(str, key)
cipher = OpenSSL::Cipher.new('RC4')
cipher.key = OpenSSL::Digest.digest('md5', key)
cipher.decrypt
Base64.encode64(cipher.update(str) + cipher.final)
end
encrypt('This is Test', 'Test')
=> "JGmpM+ewGA79qaZH\n"
def decrypt(encrypted_string, key)
decipher = OpenSSL::Cipher.new('RC4')
decipher.key = OpenSSL::Digest.digest('md5', key)
decipher.decrypt
decipher.update(Base64.decode64(encrypted_string)) + decipher.final
end
decrypt("JGmpM+ewGA79qaZH\n", "Test")
=> "This is Test"
【讨论】:
这是您需要输入的命令,将字符串foo 加密为密文:
echo -n "foo" | openssl enc -e -base64 -rc4 -nosalt -pass pass:secretkey -p
这会返回:
key=610A2EE688CDA9E724885E23CD2CFDEE
ryW2
ryW2 是您的 base64 编码密文。
我们添加了-p,因此我们可以看到用于加密的密钥。
-p 是必需的,因为 OpenSSL 使用内部函数 EVP_BytesToKey 将密码短语转换为密钥,并且没有等效的 Ruby 方法来执行此操作。因此,在 Ruby 中加密或解密时,您必须直接使用此键值,而不是密码。
解密同样简单:
echo "ryW2" | openssl enc -d -base64 -rc4 -nosalt -pass pass:secretkey
这会返回:
foo
考虑到这一切,下面是使用 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
最终,只要您知道EVP_BytesToKey 将为给定的pass 返回什么内容,加密和解密就相当简单。您可以在此处阅读有关EVP_BytesToKey 的更多信息:
【讨论】:
我很不高兴在 Ruby 中没有内置的方法来做到这一点。 My other answer 这个问题是一个功能性的解决方法,但它需要一些我不喜欢的耗时步骤。所以我写了一个名为 evp_bytes_to_key 的 gem,它会为你做的!
首先安装gem:
gem install evp_bytes_to_key
然后生成你的密文:
echo -n "foo" | openssl enc -e -base64 -rc4 -nosalt -pass pass:secretkey
这会返回:
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
更多使用这个 gem 的例子可以在README找到。
【讨论】: