如何解决 OpenSSL::Cipher::Cipher#encrypt 的弃用警告

发布于 2024-08-04 02:48:17 字数 732 浏览 4 评论 0原文

我刚刚将 Mac 升级到 Snow Leopard,并启动并运行了 Rails 环境。除了 OSX 之外,与我之前安装的唯一区别是我现在运行的是 ruby​​ 1.8.7 (2008-08-11 patchlevel 72) [universal-darwin10.0] (Snow Leopard)默认)而不是 1.8.6。

现在,当我运行代码时,我看到与 OpenSSL 相关的弃用警告

:警告:OpenSSL::Cipher::Cipher#encrypt 和 OpenSSL::Cipher::Cipher#decrypt 的参数已弃用;使用 OpenSSL::Cipher::Cipher#pkcs5_keyivgen 派生密钥和 IV

我的代码示例导致第 4 行出现这些警告(它解码加密字符串):

1. def decrypt(data)
2.  encryptor = OpenSSL::Cipher::Cipher.new('DES-EDE3-CBC')
3.  key = "my key"
4.  encryptor.decrypt(key)
5.  text = encryptor.update(data)
6.  text << encryptor.final
7. end

我正在努力了解如何解决此问题,而谷歌并没有真正提供帮助。我是否应该尝试降级到 Ruby 1.8.6(如果是这样,最好的方法是什么?),我应该尝试隐藏警告(把头埋在沙子里?!)还是有一个简单的修复方法?可以在代码中应用吗?

I've just upgraded my Mac to Snow Leopard and got my Rails environment up and running. The only difference -- OSX aside -- with my previous install is that I'm now running ruby 1.8.7 (2008-08-11 patchlevel 72) [universal-darwin10.0] (Snow Leopard default) rather than 1.8.6.

I'm now seeing deprecation warnings relating to OpenSSL when I run my code:

warning: argumtents for OpenSSL::Cipher::Cipher#encrypt and OpenSSL::Cipher::Cipher#decrypt were deprecated; use OpenSSL::Cipher::Cipher#pkcs5_keyivgen to derive key and IV

Example of my code which is causing these warnings (it decodes an encrypted string) on line 4:

1. def decrypt(data)
2.  encryptor = OpenSSL::Cipher::Cipher.new('DES-EDE3-CBC')
3.  key = "my key"
4.  encryptor.decrypt(key)
5.  text = encryptor.update(data)
6.  text << encryptor.final
7. end

I'm struggling to understand how I can resolve this, and Google isn't really helping. Should I try and downgrade to Ruby 1.8.6 (and if so, what's the best way of doing this?), should I try and just hide the warnings (bury my head in the sand?!) or is there an easy fix I can apply in the code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

彡翼 2024-08-11 02:48:17

由于 Ruby 中的隐式类型转换,旧版 Ruby 允许人们以完全错误的方式使用 PBE(基于密码的加密)。新版本修复了这个问题,所以警告是一件好事。

你的例子正好说明了问题。 Triple-DES 需要 24 字节密钥材料(包括奇偶校验),但您只提供了 6 个字节。您的密钥材料将被重复以弥补导致密钥安全性降低的缺陷。

正确的方法是使用 PKCS5 生成密钥和 IV(初始向量),它使用复杂的哈希和迭代来使密钥更加安全。

Ruby 提供了以下示例代码。 pass 是您的密钥,您可以对 salt 使用任何硬编码值。

puts "--Encrypting--"
des = OpenSSL::Cipher::Cipher.new(alg)
des.pkcs5_keyivgen(pass, salt)
des.encrypt
cipher =  des.update(text)
cipher << des.final
puts %(encrypted text: #{cipher.inspect})
puts

puts "--Decrypting--"
des = OpenSSL::Cipher::Cipher.new(alg)
des.pkcs5_keyivgen(pass, salt)
des.decrypt
out =  des.update(cipher)
out << des.final
puts %(decrypted text: "#{out}")
puts

Due to the implicit type conversion in Ruby, older Ruby allows people use PBE (Password-Based Encryption) in a totally wrong way. The newer one fixes that so the warning is a good thing.

Your example shows exactly the problem. Triple-DES requires 24-byte key material (including parity) but you only provided 6 bytes. Your key material will be repeated to make up the deficit, that resulted in a less secure key.

The correct way to do this is to generate key and IV (initial vector) with PKCS5, which use complicated hashing and iteration to make the key much more secure.

Ruby provides following sample code. pass is your key and you can use any hardcoded value for salt.

puts "--Encrypting--"
des = OpenSSL::Cipher::Cipher.new(alg)
des.pkcs5_keyivgen(pass, salt)
des.encrypt
cipher =  des.update(text)
cipher << des.final
puts %(encrypted text: #{cipher.inspect})
puts

puts "--Decrypting--"
des = OpenSSL::Cipher::Cipher.new(alg)
des.pkcs5_keyivgen(pass, salt)
des.decrypt
out =  des.update(cipher)
out << des.final
puts %(decrypted text: "#{out}")
puts
凶凌 2024-08-11 02:48:17

ZZ Coder 很接近,但没有雪茄。事实上,您不应该在 #decrypt 或 #encrypt 之前调用 Cipher#pkcs5_keyivgen。在实践中,通常它会加密得很好,但解密常常会失败。 代码应该是:

puts "--Encrypting--"
des = OpenSSL::Cipher::Cipher.new(alg)
des.encrypt
des.pkcs5_keyivgen(pass, salt)
cipher =  des.update(text)
cipher << des.final
puts %(encrypted text: #{cipher.inspect})
puts

所以

puts "--Decrypting--"
des = OpenSSL::Cipher::Cipher.new(alg)
des.decrypt
des.pkcs5_keyivgen(pass, salt)  
out =  des.update(cipher)
out << des.final
puts %(decrypted text: "#{out}")
puts

ZZ Coder was close, but no cigar. In fact, you should never call Cipher#pkcs5_keyivgen before #decrypt or #encrypt. In practice, generally it will encrypt fine, but decrypt will oft times fail. So the code should be:

puts "--Encrypting--"
des = OpenSSL::Cipher::Cipher.new(alg)
des.encrypt
des.pkcs5_keyivgen(pass, salt)
cipher =  des.update(text)
cipher << des.final
puts %(encrypted text: #{cipher.inspect})
puts

and

puts "--Decrypting--"
des = OpenSSL::Cipher::Cipher.new(alg)
des.decrypt
des.pkcs5_keyivgen(pass, salt)  
out =  des.update(cipher)
out << des.final
puts %(decrypted text: "#{out}")
puts
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文