我用类似的例子跟踪了这些线程和其他线程:
我已经实现了一个客户机/服务器简单Java程序,它使用本地生成的客户机和服务器的自签名证书。顺便说一下,他们谈判的是TLS 1.3,而不是1.2。那很好。
但是我看到他们只使用服务器证书(客户端被配置为接受任何,好的)。我要他们也要求客户进行身份验证。并允许客户端证书为任何自签名证书,不经任何CA签名.因此,我尝试服务器使用sslServerSocket.setNeedClientAuth(true)或访问客户端证书信息。然后我就会犯这样的错误:
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 --sslncat --ssl --listenopenssl s_clientopenssl s_server我的结论是,我的客户端运行良好,需要时在其他服务器上进行身份验证。但是我的服务器需要要么向客户机提供基本CA (我不想这样),要么或者只接受任何没有客户端身份验证的客户端(这就是我现在的目标)。
我希望我的服务器需要客户端证书,并接受任何证书。我怎样才能做到这一点?谢谢!
动机:我想使用Java而不是Go来实现一些同步文档丰富的特性。它们在连接的两侧使用自定义证书身份验证。
发布于 2022-06-15 20:10:52
所以现在起作用了。
首先,我只在客户端强制握手。这似乎是可以的,但是将它添加到服务器端会产生更好的错误消息。
因此,在接受连接(Groovy代码)之后,我在服务器端添加了最后一行:
ss.setNeedClientAuth(true)
SSLSocket socket = ss.accept() as SSLSocket
socket.startHandshake()然后,当客户端到达时,我得到了一个更多的指示错误:
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)因此,过了一会儿,我在代码中发现了一些可疑的东西,可以接受来自任何证书的连接:
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更改为空数组:
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 }现在它正按我的意愿运作。
https://stackoverflow.com/questions/72608363
复制相似问题