我有一个简单的安全套接字服务器-客户端程序。
对于服务器证书,我使用 keytool 创建了一个密钥库。
当我尝试通过客户端连接到服务器时,出现以下异常:
在服务器中:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
在客户端:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
如果我的理解是正确的,那么这些异常是由于我使用我创建的证书这一事实引起的。
我的问题如下:
如果我在服务器和客户端中设置启用的密码套件,所有 *_anon* 密码套件,这不应该解决问题吗?
我的意思是如果我启用*_anon_*
密码套件,则不需要身份验证,因此没有例外。
它是否正确?
因为我仍然遇到异常。我尝试在已启用的密码套件中包含所有已启用的+_anon 密码套件。没有成功。我尝试只设置 anon 并得到一个新的例外:
Exception in thread "main" java.lang.IllegalArgumentException: Name must not be null
有人可以用匿名密码套件解释为什么我会得到这些例外吗?
注意:
如果我在客户端上设置javax.net.ssl.trustStore
指向我创建并由我的服务器使用的密钥库的系统属性,则通信正常!
该程序正常工作,数据从客户端发送到服务器正常。
更新:
这是我用来启用匿名密码的片段(我已经为服务器和客户端部分做了这个):
String[] supported = server.getSupportedCipherSuites();
String[] anonCipherSuitesSupported = new String[supported.length];
int count = 0;
for(int i = 0; i < supported.length; i++)
{
if(supported[i].indexOf("_anon_") > 0)
{
anonCipherSuitesSupported[count++] = supported[i];
}
}
String[] oldEnabled = server.getEnabledCipherSuites();
String[] newEnabled = new String[oldEnabled.length + count];
System.arraycopy(oldEnabled, 0, newEnabled, 0, oldEnabled.length);
System.arraycopy(anonCipherSuitesSupported, 0, newEnabled, oldEnabled.length, count);
server.setEnabledCipherSuites(newEnabled);
堆栈跟踪位于客户端:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.writeRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppOutputStream.write(Unknown Source)
at sun.nio.cs.StreamEncoder.writeBytes(Unknown Source)
at sun.nio.cs.StreamEncoder.implFlushBuffer(Unknown Source)
at sun.nio.cs.StreamEncoder.implFlush(Unknown Source)
at sun.nio.cs.StreamEncoder.flush(Unknown Source)
at java.io.OutputStreamWriter.flush(Unknown Source)
at com.client.SSLClient1.main(SSLClient1.java:58)
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(Unknown Source)
at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)
at sun.security.validator.Validator.validate(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)
... 14 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)
at java.security.cert.CertPathBuilder.build(Unknown Source)
... 20 more
在服务器端:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Received fatal alert: certificate_unknown
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.recvAlert(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readDataRecord(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
at com.sun.net.ssl.internal.ssl.AppInputStream.read(Unknown Source)
at com.server.SecureOrderTaker.main(SecureOrderTaker.java:92)
现在,如果我只是这样做:
server.setEnabledCipherSuites(anonCipherSuitesSupported);
所以只有匿名密码套件被启用,我得到:
Exception in thread "main" java.lang.IllegalArgumentException: Name must not be null
at com.sun.net.ssl.internal.ssl.CipherSuite.valueOf(Unknown Source)
at com.sun.net.ssl.internal.ssl.CipherSuiteList.<init>(Unknown Source)
at com.sun.net.ssl.internal.ssl.SSLServerSocketImpl.setEnabledCipherSuites(Unknown Source)
at com.server.SecureOrderTaker.main(SecureOrderTaker.java:82)
谢谢