【问题标题】:Cannot set up client X509 auth in Java无法在 Java 中设置客户端 X509 身份验证
【发布时间】:2014-01-28 17:15:46
【问题描述】:

我尝试在我的 Java 应用程序中设置服务器端客户端,如下所示:

SslContextFactory sslContextFactory = new SslContextFactory();
sslContextFactory.setNeedClientAuth(true);

TrustManager[] trustManagers = new TrustManager[
        ]{new X509TrustManager() {
    @Override
    public void checkClientTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {
        LoggerFactory.getLogger().fatal("Check client trusted");
    }

    @Override
    public void checkServerTrusted(X509Certificate[] arg0, String arg1)
            throws CertificateException {
        LoggerFactory.getLogger().fatal("Check server trusted");
    }

    @Override
    public X509Certificate[] getAcceptedIssuers() {
        LoggerFactory.getLogger().fatal("Returning accepted issuers");

        try {
            InputStream inStream = new FileInputStream("/home/sk_/client.cer");
            CertificateFactory cf = CertificateFactory.getInstance("X.509");
            X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);
            inStream.close();

            return new X509Certificate[]{cert};
        } catch (Exception e) {
            e.printStackTrace();
            LoggerFactory.getLogger().fatal("AFDASDFSAASD", e);

            return null;
        }
    }
}};

SSLContext context = SSLContext.getInstance("TLSv1.1");
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
FileInputStream fin = new FileInputStream(".hive/certs/mjolnirr.jks");
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(fin, "passwd".toCharArray());

kmf.init(ks, "passwd".toCharArray());
context.init(kmf.getKeyManagers(), trustManagers, null);

SSLEngine engine = context.createSSLEngine();
engine.setNeedClientAuth(true);
engine.setEnabledCipherSuites(engine.getSupportedCipherSuites());
engine.setEnabledProtocols(engine.getSupportedProtocols());

sslContextFactory.setSslContext(context);

我还向客户端添加了 SSL 设置:

-Djavax.net.debug=ssl 
-Djavax.net.ssl.keyStoreType=jks 
-Djavax.net.ssl.keyStore=/home/sk_/client-truststore.jks 
-Djavax.net.ssl.keyStorePassword=passwd 
-Djavax.net.ssl.trustStoreType=jks 
-Djavax.net.ssl.trustStore=/home/sk_/client-truststore.jks 
-Djavax.net.ssl.trustStorePassword=passwd

client.cer 已从客户端信任库 (client-trustore.jks) 导出。客户端失败并出现以下错误:

javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:946)
at sun.security.ssl.SSLSocketImpl.waitForClose(SSLSocketImpl.java:1705)
at sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:122)
at sun.security.ssl.Handshaker.sendChangeCipherSpec(Handshaker.java:972)
at sun.security.ssl.ClientHandshaker.sendChangeCipherAndFinish(ClientHandshaker.java:1087)
...

我的申请有什么问题?

编辑我已将sslhandshake 的调试添加到服务器,这是输出:

*** ServerHelloDone
qtp935608254-28, WRITE: TLSv1 Handshake, length = 1442
qtp935608254-29, READ: TLSv1 Handshake, length = 77
*** Certificate chain
***
qtp935608254-29, fatal error: 42: null cert chain
javax.net.ssl.SSLHandshakeException: null cert chain
%% Invalidated:  [Session-1, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA]
qtp935608254-29, SEND TLSv1 ALERT:  fatal, description = bad_certificate
qtp935608254-29, WRITE: TLSv1 Alert, length = 2
qtp935608254-29, fatal: engine already closed.  Rethrowing javax.net.ssl.SSLHandshakeException: null cert chain

【问题讨论】:

  • 请使用 -Djavax.net.debug=ssl 运行服务器,握手并在此处发布相关输出。

标签: java security ssl https x509


【解决方案1】:

服务器的信任库不信任您的客户端证书。服务器发送一个受信任的 CA 列表,客户端必须发送一个受其中一个信任的证书。它不能,所以它发送了一个空证书链。如果您的客户端证书是自签名的,或者由不受信任的 CA 签名,您需要将其从客户端密钥库中导出,然后将其作为受信任的证书导入到服务器的信任库中。

【讨论】:

    猜你喜欢
    • 2017-12-11
    • 2018-10-17
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2013-02-02
    • 2014-05-01
    • 2018-03-20
    相关资源
    最近更新 更多