OpenSSL:: Cipher:: CipherError с Rails4 на JRuby
Rails4 по умолчанию использует зашифрованное хранилище сеансов cookie. Когда приложение пытается зашифровать файл cookie, возникает следующая ошибка: OpenSSL::Cipher::CipherError: Illegal key size: possibly you need to install Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files for your JRE
(stacktrace: https://gist.github.com/8ba56b18060ae30e4d44).
Как упоминалось здесь, это можно обойти, понизив криптографию или установив JCE - первое, что я действительно не хочу делать, и последнее невозможно (афайк) на героку.
Ответы
Ответ 1
Не уверен, что он будет работать на Heroku, но это разрешает проблему на моем локальном Jruby.
Создать config/initializers/unlimited_strength_cryptography.rb:
if RUBY_PLATFORM == 'java' # Allows the application to work with other Rubies if not JRuby
require 'java'
java_import 'java.lang.ClassNotFoundException'
begin
security_class = java.lang.Class.for_name('javax.crypto.JceSecurity')
restricted_field = security_class.get_declared_field('isRestricted')
restricted_field.accessible = true
restricted_field.set nil, false
rescue ClassNotFoundException => e
# Handle Mac Java, etc not having this configuration setting
$stderr.print "Java told me: #{e}n"
end
end
Ответ 2
В Центре Heroku Dev теперь есть эта статья: "Настройка JDK" .
В некоторых случаях файлы необходимо связывать с JDK, чтобы выявить функциональность в JVM времени выполнения. Например, включение неограниченной прочности Java Cryptography Extensions (JCE) часто добавляется в JDK для использования более сильных криптографических библиотек. Чтобы справиться с такими случаями, Heroku скопирует файлы, указанные приложением в папку .jdk-overlay, в структуру каталогов JDK.
Здесь, как добавить файлы JCE в ваше приложение:
Ответ 3
Используя подход Leons, это решило мою проблему в производстве, но сломало dev без спасения.
# config/initializers/unrestricted_crypto.rb
begin # Enable 'restricted' cipher libraries on crippled systems
prop = Java::JavaxCrypto::JceSecurity.get_declared_field 'isRestricted'
prop.accessible = true
prop.set nil, false
rescue NameError
end
Это потому, что у разных джавов разные флавы...... Я отпущу себя.