NoMethodError при попытке расшифровать данные с помощью Blowfish

Я пытаюсь расшифровать некоторые данные, которые я извлекаю из API, и получаю странные ошибки.

Небольшая предыстория

Данные, которые я получаю, были зашифрованы с помощью Blowfish, а затем закодированы в строку base64 и доступны в строке JSON. Вот пример того, как выглядит эта строка JSON

{"payload":"BR0UzF38W4oVB7fjP6WgClqdaMKIYTl661mpneqoXQYIYkBQvjlMQZ+yn...."} 

В моем скрипте Ruby я делаю следующее:

require 'crypt/blowfish'
require 'base64'

# get json data
response = Net::HTTP.get(URI('http://www.url-to-json.com'))
results  = JSON.parse(response)

# decode the base64 results
decoded = Base64.decode64(results['payload'])

# setup blowfish object with key
blowfish = Crypt::Blowfish.new('my_secret_key')

# decrypt the data
puts blowfish.decrypt_string(decoded)

И это ошибка, которая возвращается:

/Users/Ken/.rvm/gems/ruby-1.9.3-p327@vs/gems/crypt-2.2.1/lib/crypt/stringxor.rb:4:in `^': undefined method `b' for "java.uti":String (NoMethodError)
    from /Users/Ken/.rvm/gems/ruby-1.9.3-p327@vs/gems/crypt-2.2.1/lib/crypt/cbc.rb:62:in `decrypt_stream'
    from /Users/Ken/.rvm/gems/ruby-1.9.3-p327@vs/gems/crypt-2.2.1/lib/crypt/cbc.rb:115:in `decrypt_string'
    from /Users/Ken/Code/vs/scripts/test.rb:55:in `run'
    from init.rb:43:in `<main>'

Есть ли у вас какие-либо сведения о том, что может быть причиной этой ошибки? Я отлаживал его часами и, похоже, не добился никакого прогресса. Я думаю, что это проблема с кодировкой, но когда я принудительно использую кодировку с помощью force_encoding(), я получаю те же ошибки.

И если вам интересно, для этого приложения я заблокирован на Ruby версии 1.9.3-p327.

Заранее благодарю за любую помощь!


person Ken    schedule 31.08.2016    source источник
comment
Выглядит как ошибка в crypt gem для меня, но не могу подтвердить. Работает ли это, когда вы предоставляете данные, созданные вручную?   -  person Felix    schedule 31.08.2016


Ответы (1)


Виновником является этот b метод. Он был представлен в Ruby 2.0. Как вы можете видеть в документации, он возвращает копию строки с кодировкой ASCII-8BIT. Вы можете либо обновить версию ruby, либо класс String с обезьяньим патчем, чтобы добавить этот метод. Обычно это реализовано на C, но я думаю, что эта реализация Ruby также будет работать:

class String
  def b
    self.dup.force_encoding("ASCII-8BIT")
  end
end
person Michał Młoźniak    schedule 31.08.2016