2009-08-28 3 views
2

Я только что обновил свой Mac до Snow Leopard и заработал среду Rails. Единственное отличие - OSX в стороне - с моей предыдущей установкой я теперь запускаю ruby 1.8.7 (2008-08-11 patchlevel 72) [universal-darwin10.0] (Snow Leopard по умолчанию), а не 1.8.6.Как разрешить предупреждения об устаревании для OpenSSL :: Cipher :: Cipher # encrypt

Я теперь вижу устаревание предупреждения, относящееся к OpenSSL, когда я запускаю мой код:

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

Пример моего код, который вызывает эти предупреждения (он декодирует зашифрованную строку) в строке 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 

Я изо всех сил пытаюсь понять, как я могу это разрешить, и Google на самом деле не помогает. Должен ли я попытаться перейти на Ruby 1.8.6 (и если да, то как это лучше всего сделать?), Я должен попытаться просто скрыть предупреждения (похоронить мою голову в песке ?!) или есть простое исправление I может применяться в коде?

ответ

3

Из-за неявного преобразования типов в Ruby, старый Ruby позволяет пользователям использовать PBE (шифрование на основе паролей) совершенно неправильно. Новым является то, что предупреждение - это хорошо.

Ваш пример показывает именно эту проблему. Для Triple-DES требуется 24-байтовый ключевой материал (включая четность), но вы предоставили только 6 байтов. Ваш ключевой материал будет повторяться, чтобы восполнить дефицит, что привело к менее безопасному ключу.

Правильный способ сделать это - сгенерировать ключ и IV (начальный вектор) с помощью PKCS5, которые используют сложное хеширование и итерацию, чтобы сделать ключ намного более безопасным.

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 
+0

Смотрите примечание ниже о упорядочении звонков в '' decrypt' и pkcs5_keyivgen'. – jrdioko

+0

См. Также новую [документацию] (https://github.com/ruby/ruby/blob/trunk/ext/openssl/ossl.c#L409). – jrdioko

1

ZZ Coder был близок, но не сигары. На самом деле, вы должны никогда вызывать Cipher # pkcs5_keyivgen перед #decrypt или #encrypt. На практике, как правило, он будет шифровать штраф, но дешифрование будет часто прерываться. Таким образом, код должен быть:

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