从 JRuby 向不支持 JRuby SSL 密码的服务发送 HTTPS 请求



基本上就是标题所说的,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

但它只会导致"套接字关闭"错误,只使用这个惊人的单行代码的变体,我设法查明了问题 - 缺乏兼容的密码。

由于 JRuby 的 Manticore HTTP 客户端似乎使用不同的加密适配器来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

在这一点上,我暂时放弃了这种方法。Manticore确实打开了一些API让你玩org.apache.http.impl.client.HttpClientBuilder但Java-fu很快就让我的眼睛变得水汪汪的。

在这一点上,我甚至想遵循"从JRuby调用Java"的荣耀,了解Java HTTP库的生态系统等等,但这不是我的强项,我时间紧迫。

有没有一个善良和知识渊博的灵魂可以提供帮助?我正在寻找其中之一:

  1. 让螳螂工作
  2. 一个Java 8包装器,接受证书/密钥作为字符串并发送HTTP请求+一种从Ruby调用它的方法
  3. 我缺少其他选项吗?

最后,经过大量的研究和懊恼,我们编写了一个 Java 库来发送 HTTP 请求并公开了这个特定用例的相关参数。为 JRuby 编写 Java 通常是两全其美的,但在这种情况下 - 需求如此简单 - 它非常轻松。

以下是最后红宝石面的样子:

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

相关内容

  • 没有找到相关文章

最新更新