Apache HIVE JDBC: 如何自定义SSL证书验证?

huangapple 未分类评论81阅读模式
英文:

Apache HIVE JDBC: How to customize SSL certificate validation?

问题

我想知道如何在Java中为Apache HIVE JDBC驱动程序自定义SSL证书验证。这包括启用使用自签名证书以及忽略其他验证错误。

以下是抛出错误的代码:

  1. // 使用库 hive-jdbc-3.1.2-standalone.jar
  2. Class.forName("org.apache.hive.jdbc.HiveDriver");
  3. Connection con = DriverManager.getConnection("jdbc:hive2://somethingsomethinghere.azurehdinsight.net:443/default;transportMode=http;ssl=true;httpPath=/hive2", "user@somedomain.com", "ultra-secure password");

如果代码能够工作,将建立与HIVE的连接,并相应地设置con。然而,我收到以下错误:

  1. java.sql.SQLException: 无法通过JDBC Uri打开客户端传输:jdbc:hive2://somethingsomethinghere.azurehdinsight.net:443/default;transportMode=http;ssl=true;httpPath=/hive2:无法建立与jdbc:hive2://somethingsomethinghere.azurehdinsight.net:443/default;transportMode=http;ssl=true;httpPath=/hive2;sasl.qop=auth的连接:javax.net.ssl.SSLPeerUnverifiedException: 主机名'123.123.123.123'与对等方提供的证书主题不匹配(CN=*.azurehdinsight.net)
  2. at org.apache.hive.jdbc.HiveConnection.<init>(HiveConnection.java:256)
  3. at org.apache.hive.jdbc.HiveDriver.connect(HiveDriver.java:107)
  4. at java.sql.DriverManager.getConnection(Unknown Source)
  5. at java.sql.DriverManager.getConnection(Unknown Source)
  6. at MyFancyButNotWorkingClass.main(MyFancyButNotWorkingClass.java:102)

很明显,将证书添加到密钥库并没有帮助,因为它似乎是为错误的服务器。然而,我(徒劳)的希望是,即使由不同服务器使用,也会接受受信任的证书(这显然会破坏SSL服务器证书的身份验证概念)。

一些证书可以通过将它们添加到本地密钥库中变得可信,例如https://self-signed.badssl.com的示例证书。以下是如何将其添加到密钥库的方式:

  1. %JAVA_HOME%\bin\keytool.exe" -import -file <CERTIFICATE-FILE-NAME> -alias <SOME-NAME> -keystore my-sample-store

配置SSL验证过程的一般方法在Apache HTTP Components - 连接管理 - SSL中有文档记录。根据这份文档(以及在本论坛和其他地方的一些研究),我得出了以下代码:

  1. SSLContext sslContext = SSLContext.getDefault();
  2. HostnameVerifier hostnameVerifier = new NoopHostnameVerifier();
  3. SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
  4. Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
  5. .register("http", PlainConnectionSocketFactory.getSocketFactory())
  6. .register("https", sslSocketFactory)
  7. .build();

由于这没有效果,我查看了HiveConnection.java的实现,发现SSLConnectionSocketFactory是使用不可配置的DefaultHostnameVerifier初始化的。

我是否遗漏了什么?是否有一种方法可以设置JVM范围内的标准HTTP客户端工厂设置,然后HIVE实现将使用这些设置?

英文:

I wonder how I can customize the SSL certificate validation for the Apache HIVE JDBC driver in Java. This includes enabling the use of self-signed certificates as well as ignoring other validation errors.

This is the code throwing an error:

  1. // using library hive-jdbc-3.1.2-standalone.jar
  2. Class.forName(&quot;org.apache.hive.jdbc.HiveDriver&quot;);
  3. Connection con = DriverManager.getConnection(&quot;jdbc:hive2://somethingsomethinghere.azurehdinsight.net:443/default;transportMode=http;ssl=true;httpPath=/hive2&quot;, &quot;user@somedomain.com&quot;, &quot;ultra-secure password&quot;);

If the code would work, a connection to HIVE would be established and con would be set accordingly. Instead I get this error:

  1. java.sql.SQLException: Could not open client transport with JDBC Uri: jdbc:hive2://somethingsomethinghere.azurehdinsight.net:443/default;transportMode=http;ssl=true;httpPath=/hive2: Could not establish connection to jdbc:hive2://somethingsomethinghere.azurehdinsight.net:443/default;transportMode=http;ssl=true;httpPath=/hive2;sasl.qop=auth: javax.net.ssl.SSLPeerUnverifiedException: Host name &#39;123.123.123.123&#39; does not match the certificate subject provided by the peer (CN=*.azurehdinsight.net)
  2. at org.apache.hive.jdbc.HiveConnection.&lt;init&gt;(HiveConnection.java:256)
  3. at org.apache.hive.jdbc.HiveDriver.connect(HiveDriver.java:107)
  4. at java.sql.DriverManager.getConnection(Unknown Source)
  5. at java.sql.DriverManager.getConnection(Unknown Source)
  6. at MyFancyButNotWorkingClass.main(MyFancyButNotWorkingClass.java:102)

It is rather obvious that added the certificate to the key store does not help as it seems to be for the wrong server. However, my (vain) hope was that a trusted certificate would be accepted even if used by a different server (which clearly would break the concept of SSL server certificates for authentication).

Some certificates can be made trustworthy by adding them to a local key store, e.g. the sample certificate of https://self-signed.badssl.com. This is how it is added to a key store:

  1. %JAVA_HOME%\bin\keytool.exe&quot; -import -file &lt;CERTIFICATE-FILE-NAME&gt; -alias &lt;SOME-NAME&gt; -keystore my-sample-store

The general approach to configure the SSL validation process is documented in Apache HTTP Components - Connection Management - SSL. With this documentation (and some research on in this forum and others) I ended up with this code:

  1. SSLContext sslContext = SSLContext.getDefault();
  2. HostnameVerifier hostnameVerifier = new NoopHostnameVerifier();
  3. SSLConnectionSocketFactory sslSocketFactory = new SSLConnectionSocketFactory(sslContext, hostnameVerifier);
  4. Registry&lt;ConnectionSocketFactory&gt; socketFactoryRegistry = RegistryBuilder.&lt;ConnectionSocketFactory&gt; create().register(&quot;http&quot;, PlainConnectionSocketFactory.getSocketFactory()).register(&quot;https&quot;, sslSocketFactory).build();

As this had no effect I looked into the implementation of HiveConnection.java and found that the SSLConnectionSocketFactory is initialized using a non-configurable DefaultHostnameVerifier.

Am I missing something here? Is there a way to set JVM-wide standard HTTP Client Factory settings that the HIVE implementation will then use?

答案1

得分: 0

如果这能稍作安慰的话,Hive JDBC的版本号<3.x的jar包即使使用DefaultHostnameVerifier也能正常工作。
关于同样错误的问题,已经在GitHub上开了一个问题 链接

英文:

If It's any consolation, Hive JDBC version &lt; 3.x jars are working even with DefaultHostnameVerifier.
There is a Github issue opened for the same error Link

huangapple
  • 本文由 发表于 2020年4月7日 22:21:08
  • 转载请务必保留本文链接:https://java.coder-hub.com/61082215.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定