ruby-on-rails - rails openssl 来自代码和终端的不同加密结果
问题描述
当我尝试从终端加密数据时
echo -n "TestData" | openssl enc -aes-256-cbc -a -K C81E728D9D4C2F636F067F89CC14862C65990ABE58735B91B6B8798E8CE45F22 -iv D342F9C6310F6B21E97AB38595BD8CAA
比我收到的 Base64 编码结果是
VJwJBTtVntJvRGkD24S4wg==
但是,当我使用完全相同的键和初始化向量对 rails 尝试相同的事情时
cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
cipher.encrypt
cipher.key = "C81E728D9D4C2F636F067F89CC14862C65990ABE58735B91B6B8798E8CE45F22"
cipher.iv = "D342F9C6310F6B21E97AB38595BD8CAA"
encrypted_data = cipher.update("TestData")
encrypted_data << cipher.final
Base64.strict_encode64(encrypted_data)
比我收到完全不同的 Base64 编码结果
qavpNrU7llgauAyyEZz/bw==
有人可以指出我错过了什么吗?
解决方案
您将key
andiv
属性作为十六进制字符串提供,但预期格式是原始字节。使用以下脚本将它们转换为二进制会产生预期的结果:
require 'openssl'
require 'base64'
def hex_to_bin(s)
s.scan(/../).map { |x| x.hex.chr }.join
end
cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
cipher.encrypt
cipher.key = hex_to_bin("C81E728D9D4C2F636F067F89CC14862C65990ABE58735B91B6B8798E8CE45F22")
cipher.iv = hex_to_bin("D342F9C6310F6B21E97AB38595BD8CAA")
encrypted_data = cipher.update("TestData")
encrypted_data << cipher.final
puts Base64.strict_encode64(encrypted_data)
(hex_to_bin
函数来源:To Hex and Back (With Ruby))。
调用它encrypt.rb
,这是运行它的结果:
$ ruby encrypt.rb
encrypt.rb:8: warning: constant OpenSSL::Cipher::Cipher is deprecated
VJwJBTtVntJvRGkD24S4wg==
为了摆脱“已弃用”警告,我不得不将弃用的类替换OpenSSL::Cipher::Cipher
为 OpenSSL::Cipher
.
推荐阅读
- php - 如何从 CodeIgniter 查询生成器中的 like 子句中删除 % 字符?
- codenameone - 如何在 Codenameone 中使用 LocationManager 获取 NMEA 帧
- python - Python 在长 windows cmd 批处理命令行上跳过单个字符
- postgresql - PostgreSQL 哈希索引和不等式
- visual-studio-code - VSCode 命令行参数
- jenkins - 詹金斯,AWS。EC2 从站
- mysql - UPDATE 语句以连续更新多个字段
- web-push - Web 推送通知更新 VAPID 密钥
- c# - .Net Core XmlDocument 不返回声明
- spring-boot - BCryptPasswordEncoder 会自动编码 Spring Security 创建的默认密码吗?