首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Java SSLServerSocket:请求客户端证书,允许任何客户端证书

Java SSLServerSocket:请求客户端证书,允许任何客户端证书
EN

Stack Overflow用户
提问于 2022-06-13 19:56:29
回答 1查看 134关注 0票数 0

我用类似的例子跟踪了这些线程和其他线程:

我已经实现了一个客户机/服务器简单Java程序,它使用本地生成的客户机和服务器的自签名证书。顺便说一下,他们谈判的是TLS 1.3,而不是1.2。那很好。

但是我看到他们只使用服务器证书(客户端被配置为接受任何,好的)。我要他们也要求客户进行身份验证。并允许客户端证书为任何自签名证书,不经任何CA签名.因此,我尝试服务器使用sslServerSocket.setNeedClientAuth(true)或访问客户端证书信息。然后我就会犯这样的错误:

代码语言:javascript
复制
Exception in thread "main" javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at java.base/sun.security.ssl.SSLSessionImpl.getPeerPrincipal(SSLSessionImpl.java:1122)
    at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)

因此,我一直在使用这些工具来测试我的实现的两个方面:

  • ncat --ssl
  • ncat --ssl --listen
  • openssl s_client
  • openssl s_server

我的结论是,我的客户端运行良好,需要时在其他服务器上进行身份验证。但是我的服务器需要要么向客户机提供基本CA (我不想这样),要么或者只接受任何没有客户端身份验证的客户端(这就是我现在的目标)。

我希望我的服务器需要客户端证书,并接受任何证书。我怎样才能做到这一点?谢谢!

动机:我想使用Java而不是Go来实现一些同步文档丰富的特性。它们在连接的两侧使用自定义证书身份验证。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-06-15 20:10:52

所以现在起作用了。

首先,我只在客户端强制握手。这似乎是可以的,但是将它添加到服务器端会产生更好的错误消息。

因此,在接受连接(Groovy代码)之后,我在服务器端添加了最后一行:

代码语言:javascript
复制
ss.setNeedClientAuth(true)
SSLSocket socket = ss.accept() as SSLSocket
socket.startHandshake()

然后,当客户端到达时,我得到了一个更多的指示错误:

代码语言:javascript
复制
Exception in thread "main" javax.net.ssl.SSLException: Cannot read the array length because "caCerts" is null
at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:133)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:371)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:314)
at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:309)
at java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1702)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:465)
at java.base/sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:421)
at javax.net.ssl.SSLSocket$startHandshake.call(Unknown Source)

因此,过了一会儿,我在代码中发现了一些可疑的东西,可以接受来自任何证书的连接:

代码语言:javascript
复制
def x509TrustAllCerts = new X509TrustManager() {
        X509Certificate[] getAcceptedIssuers() {
            return null // <--- SUSPICIOUS!!
        }
        void checkClientTrusted(X509Certificate[] certs, String authType) { }
        void checkServerTrusted(X509Certificate[] certs, String authType) { }
    }
TrustManager[] trustAllCerts = new TrustManager[] { x509TrustAllCerts }

因此,我做了最简单的修正,将null更改为空数组:

代码语言:javascript
复制
def x509TrustAllCerts = new X509TrustManager() {
        X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0] // <-- FIX
        }
        void checkClientTrusted(X509Certificate[] certs, String authType) { }
        void checkServerTrusted(X509Certificate[] certs, String authType) { }
    }
TrustManager[] trustAllCerts = new TrustManager[] { x509TrustAllCerts }

现在它正按我的意愿运作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72608363

复制
相关文章

相似问题

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