Отправка HTTPS-запросов в службу, которая не поддерживает SSL-шифры JRuby, от JRuby - PullRequest
0 голосов
/ 27 июня 2018

Это в основном то, что написано в заголовке: шифры не поддерживаются в jruby-openssl, и у меня возникла производственная проблема. Мне нужен один из них:

ECDHE-RSA-AES256-GCM-SHA384 TLS1.2
ECDHE-RSA-AES256-SHA384 TLS1.2
ECDHE-RSA-AES256-CBC-SHA TLS1.2
ECDHE-ECDSA-AES256-SHA384 TLS1.2
ECDHE-ECDSA-AES256-SHA TLS1.2
ECDH-RSA-AES256-SHA384 TLS1.2
ECDH-ECDSA-AES256-SHA384 TLS1.2
ECDH-RSA-AES256-SHA TLS1.2
ECDH-ECDSA-AES256-SHA TLS1.2

из всех этих - 1 поддерживается MRI Ruby AES256-SHA256 (согласно номенклатуре OpenSSL), но MRI Ruby не является опцией. Тем не менее.

Основной сценарий, с которым я играл, это:

uri = URI.parse(ds_url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.ssl_version = :"TLSv1_2"
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # OpenSSL::SSL::VERIFY_PEER, OpenSSL::SSL::VERIFY_NONE
http.cert = client_cert
http.key = client_key
http.ca_file = ds_cert_file
http.ciphers = OpenSSL::SSL::SSLContext.new.ciphers.map do |c|
  c[0].gsub("-", "+")
end
puts http.ciphers.inspect

resp = http.post(uri.request_uri, http_body, 'Content-Type' => 'application/xml; charset=utf-8')
resp.body

но это просто приводит к ошибке «закрытое гнездо», только играя с вариацией этого удивительного однострочного Мне удалось точно определить проблему - отсутствие совместимых шифров.

Начиная с HTTP-клиент Manticore для JRuby , похоже, использует другой крипто-адаптер для BouncyCastle Я тоже пробовал его, но этот только что начал втягивать меня в червоточину забавных ошибок Java, таких как

java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException : algid parse error, not a sequence

Код для реализации manticore похож:

client = Manticore::Client.new(socket_timeout: 5, ssl: {
  ca_file: "ca.pem",
  client_cert: 'cert.pem',
  client_key:  'key.pem'
}) do |http_client_builder, request_builder|
  binding.pry
end
rv = client.post(ds_url)
rv.body

и это приводит к вышеупомянутой ошибке, затем все становится горячее с:

PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

и в этот момент я отказался от этого подхода, пока. Мантикора открывает некоторые apis, чтобы вы могли поиграть с org.apache.http.impl.client.HttpClientBuilder, но Java-фу быстро заставляет мои глаза слезиться.

На данный момент, я даже испытываю соблазн проследить за славой «вызова Java из JRuby», изучения эко-системы Java HTTP libs и всего такого, но это не совсем моя сильная сторона, и я привязанный к времени.

Есть ли добрая и знающая душа, которая может помочь? Я ищу один из них:

  1. заставить мантикор работать
  2. Оболочка Java 8, которая принимает сертификаты / ключи в виде строк и отправляет HTTP-запрос + способ вызова из Ruby
  3. какие-либо другие опции, которые я пропускаю?

1 Ответ

0 голосов
/ 29 января 2019

В конце, после долгих исследований и огорчений, мы написали библиотеку Java, которая отправляет HTTP-запросы и выставляет соответствующие аргументы для этого конкретного варианта использования. Написание Java для JRuby, как правило, худшее из обоих миров, но в этом случае - требования были настолько просты - это было довольно безболезненно.

Вот как все выглядит в конце ruby-side:

java_import "com.mycompany.http.HttpClient"
java_import "com.mycompany.http.SSLOptions"

#
# ...
#

ssl_options = SSLOptions.createFromStrings client_cert, client_key, ca_cert

rv = HttpClient.create(url, ssl_options, 60000, "changeit", "changeit").send(request)
if rv.responseSuccess
  # log.merge(response: rv.responseSuccess.payload)
  rv.responseSuccess.payload
else
  raise rv.responseFailure.cause
end
...