首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >用于身份验证的Apache HttpClient 4.3和x509客户端证书

用于身份验证的Apache HttpClient 4.3和x509客户端证书
EN

Stack Overflow用户
提问于 2014-03-24 18:21:29
回答 1查看 21K关注 0票数 5

现在,我正在寻找关于如何通过HttpComponentsMessageSender重写客户端x509证书身份验证的过时解决方案的解决方案(与此无关)。

例如,不推荐使用的解决方案是:

代码语言:javascript
复制
    SSLSocketFactory lSchemeSocketFactory = new SSLSocketFactory(this.keyStore, this.keyStorePassword);
    Scheme sch = new Scheme("https", 443, lSchemeSocketFactory);

    DefaultHttpClient httpClient = (DefaultHttpClient)getHttpClient();
    httpClient.getConnectionManager().getSchemeRegistry().register(sch);

作为我使用CloseableHttpClient的新解决方案,我使用:

代码语言:javascript
复制
    SSLContextBuilder sslContextBuilder = SSLContexts.custom()
            // this key store must contain the key/cert of the client
            .loadKeyMaterial(keyStore, keyStorePassword.toCharArray());

    if (trustStore != null) {
        // this key store must contain the certs needed and trusted to verify the servers cert
        sslContextBuilder.loadTrustMaterial(trustStore);
    }

    SSLContext sslContext = sslContextBuilder.build();

    LayeredConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext);

    // Create a registry of custom connection socket factories for supported
    // protocol schemes / https
    Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
            .register("https", sslsf)
            .register("http", new PlainConnectionSocketFactory())
            .build();

    PoolingHttpClientConnectionManager connPoolControl =
            new PoolingHttpClientConnectionManager(socketFactoryRegistry);
    setConnPoolControl(connPoolControl);
    getClientBuilder().setSSLSocketFactory(sslsf);

我仍然得到403禁止从服务器。但是当我使用“弃用”版本的解决方案时,它工作得很好。SSL证书由Thawte签名。

有什么想法吗?谢谢

EN

回答 1

Stack Overflow用户

发布于 2017-05-09 05:53:14

您需要创建一个包含可信CA的密钥库,即trust.jks。在这个密钥库中,您应该只放入应用程序将要连接的服务器的证书。

然后,您需要一个用于服务器标识的密钥库,即identity.jks。在这个密钥库中,您应该存储将私钥+证书+ CA链放在一个别名(一个名称)下,您的应用程序将使用该别名向服务器进行身份验证。

然后,您可以像这样构建HttpClient

代码语言:javascript
复制
public static HttpClient getHttpClient() throws KeyStoreException, CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableKeyException, KeyManagementException {

    KeyStore identityKeyStore = KeyStore.getInstance("jks");
    identityKeyStore.load(MyClass.class.getClassLoader().getResourceAsStream("identity.jks"), "identity_password".toCharArray());

    KeyStore trustKeyStore = KeyStore.getInstance("jks");
    trustKeyStore.load(MyClass.class.getClassLoader().getResourceAsStream("trust.jks"), "trust_password".toCharArray());

    SSLContext sslContext = SSLContexts
            .custom()
            // load identity keystore
            .loadKeyMaterial(identityKeyStore, "identity_password".toCharArray(), new PrivateKeyStrategy() {
                @Override
                public String chooseAlias(Map<String, PrivateKeyDetails> aliases, Socket socket) {
                    return "identity_alias";
                }
            })
            // load trust keystore
            .loadTrustMaterial(trustKeyStore, null)
            .build();

    SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext,
            new String[]{"TLSv1.2", "TLSv1.1"},
            null,
            SSLConnectionSocketFactory.getDefaultHostnameVerifier());

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

要构建identity.jks,您需要CAs链、公钥和私钥:

代码语言:javascript
复制
$1 = mycustomidentity

# make the keycert bundle for pkcs12 keystore
cat intermediate/certs/ca-chain.cert.pem \
    intermediate/certs/$1.cert.pem \
    intermediate/private/$1.key.pem \
    > intermediate/keycerts/$1.full-chain.keycert.pem

# generate the pkcs12 keystore with the alias of the server url
openssl pkcs12 -export \
    -in intermediate/keycerts/$1.full-chain.keycert.pem \
    -out intermediate/pkcs12s/$1.full-chain.p12 \
    -name $1 \
    -noiter -nomaciter

# .p12 to .jks
keytool -importkeystore -srckeystore $1.full-chain.p12 \
    -srcstoretype pkcs12 -srcalias $1 \
    -destkeystore identity.jks -deststoretype jks \
    -deststorepass identity_password -destalias identity_alias

对于trust.jks文件,您只需要服务器的证书(请参阅https://stackoverflow.com/a/36427118/2692914https://stackoverflow.com/a/7886248/2692914),更改别名没有问题:

代码语言:javascript
复制
# .crt, .cer into a .jks
keytool -import -alias trust_alias -file server_certificate.crt \
    -keystore trust.jks
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22606579

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档