How to resolve deprecation warnings for OpenSSL::Cipher::Cipher#encrypt

对着背影说爱祢 提交于 2019-12-04 14:22:48

问题


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?


回答1:


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



回答2:


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


来源:https://stackoverflow.com/questions/1349397/how-to-resolve-deprecation-warnings-for-opensslciphercipherencrypt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!