HttpClient始终使用密钥库中的第一个证书条目。

huangapple go评论72阅读模式
英文:

HttpClient takes always the first certificate entry form KeyStore

问题

我有两个不同的密钥库service1.jksservice2.jks,分别对应于两个不同的服务(尽管它们具有相同的根证书)。这是我的httpClient,它与这两个服务成功通信:

  public HttpClient getHttpClient(String filePath, String password) {
    KeyStore keyStore = KeyStore.getInstance(new File(filePath), password.toCharArray());

    SSLContext sslContext = new SSLContextBuilder()
            .loadKeyMaterial(keyStore, password.toCharArray())
            .build();

    SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, (hostname, session) -> true);

    return HttpClients.custom()
            .setSSLSocketFactory(socketFactory)
            .build();
  }

我需要在项目中只使用一个共享的密钥库。因此,我将service1.jksservice2.jks合并为一个常用密钥库common.jks

cp service2.jks common.jks
keytool -importkeystore -srckeystore service1.jks -srcstoretype jks -srcstorepass changeit -destkeystore common.jks -deststoretype jks -deststorepass changeit

因此,common.jks 现在有两个条目:

$ keytool -list -storepass changeit -keystore common.jks
密钥库类型: JKS
密钥库提供方: SUN

您的密钥库中包含 2 个条目

service1-alias, 8 сент. 2020 г., PrivateKeyEntry,
证书指纹 (SHA-256): 
....
service2-alias, 8 сент. 2020 г., PrivateKeyEntry,
证书指纹 (SHA-256): 
...

然后,问题出现在我的 HttpClient 中,现在它只与第一个 service1 成功通信,而对 service2 的请求变为未经授权。对我来说,似乎 HttpClient 现在只使用了 common.jks 中的第一个条目。如何使 HttpClient 使用请求的正确别名?

英文:

I have two different keyStores service1.jks and sevice2.jks for two different services correspondingly (but they have the same RootSertificate though). Here is my httpClient which works successfully with the two services:

  public HttpClient getHttpClient(String filePath, String password) {
    KeyStore keyStore = KeyStore.getInstance(new File(filePath), password.toCharArray());

    SSLContext sslContext = new SSLContextBuilder()
            .loadKeyMaterial(keyStore, password.toCharArray())
            .build();

    SSLConnectionSocketFactory socketFactory = new SSLConnectionSocketFactory(sslContext, (hostname, session) -> true);

    return HttpClients.custom()
            .setSSLSocketFactory(socketFactory)
            .build();
  }

I have a need to use only one shared keyStore in my project. So I merged service1.jks and sevice2.jks into one common keyStore common.jks:

cp sevice2.jks common.jks
keytool -importkeystore -srckeystore service1.jks -srcstoretype jks -srcstorepass changeit -destkeystore common.jks -deststoretype jks -deststorepass changeit

So common.jks has two items:

$ keytool -list -storepass changeit -keystore server.keystore.jks
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

service1-alias, 8 сент. 2020 г., PrivateKeyEntry,
Certificate fingerprint (SHA-256): 
....
service2-alias, 8 сент. 2020 г., PrivateKeyEntry,
Certificate fingerprint (SHA-256): 
...

Then it turned out that my HttpClient now works successfully only with the first service1, while requests to service2 became unauthorized. It seems for me that my HttpClient takes now only the first entry form common.jks. How to make HttpClient to use the correct alias for the request?

答案1

得分: 2

我相信这是默认行为。在 SSLContextBuilder 的 Javadocs 中有一个 注释

> 请注意:SSLContext.init(KeyManager[],TrustManager[],SecureRandom) 的默认 Oracle JSSE 实现接受多个密钥和信任管理器,但只会使用第一个匹配的类型。例如,请参阅:SSLContext.html#init

许多 Java 库和框架都存在这个问题 - 证书可以存储在带有别名的密钥库中,原则上,如果应用程序必须呈现证书,它可以选择使用哪个别名。然而,执行此操作的功能通常会从库中省略,假设应用程序永远不需要使用多个密钥库。

英文:

I believe this is the default behaviour. There's a note in the Javadocs for SSLContextBuilder:

> Please note: the default Oracle JSSE implementation of
> SSLContext.init(KeyManager[], TrustManager[], SecureRandom) accepts
> multiple key and trust managers, however only only first matching type
> is ever used. See for example: SSLContext.html#init

Many Java libraries and frameworks have this problem -- certificates can be stored in a keystore with a alias and, in principle, an application can select which alias to use if it has to present a certificate. However, facilities to do this are often ommited from libraries, on the assumption that an application will never need to use more than a single keystore.

huangapple
  • 本文由 发表于 2020年9月8日 18:52:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/63792398.html
匿名

发表评论

匿名网友

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

确定