java安全套接字没有认证? [英] java secure socket without authentication?

查看:151
本文介绍了java安全套接字没有认证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个简单的安全套接字服务器 - 客户端程序。

对于服务器证书,我使用keytool创建了一个密钥库。

当我尝试通过我连接到服务器时客户端我得到以下异常:

在服务器中:

I have a trivial secure socket server-client program.
For the server certificates, I created a keystore using keytool.
When I try to connect to the server by my client I get these exceptions:
In server:

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)

如果我的理解是正确的,这些例外是由于我使用我创建的证书引起的。

我的问题如下:

如果我在启用的c中设置ipher套件,无论是在服务器还是在客户端,所有的* _anon *密码套件都不应该解决这个问题吗?

我的意思是如果我启用 * _ anon _ * 密码套件然后不需要身份验证,因此没有例外。

这是正确的吗?

因为我仍然得到例外。我尝试在启用的密码套件中启用所有启用的+ _anon密码套件。没有成功。我尝试只设置anon并获得一个新例外:

If my understanding is correct, these exceptions are caused due to the fact, that I am using certificates I created.
My question is the following:
If I set in the enabled cipher suites, both in server and in client, all the *_anon* cipher suites, shouldn't this solved the problem?
I mean If I enable the *_anon_* cipher suites then no authentication would be needed hence no exceptions.
Is this correct?
Because I still get exceptions. I tried having in the enabled cipher suites all the enabled+the _anon ones. No success. I tried setting only the anon ones and got a new exception:

Exception in thread "main" java.lang.IllegalArgumentException: Name must not be null

有人可以用anon密码套件解释为什么我会得到这些例外吗?< br>
注意:

如果我在客户端上设置系统属性 javax.net.ssl.trustStore 指向我创建并由我的服务器使用的密钥库,通信正常!

该程序无异常工作,数据从客户端发送到服务器。

Could someone please explain why I get these exceptions, with the anon cipher suites?
Note:
If I set on the client the system property javax.net.ssl.trustStore pointing to the keystore I created and being used by my server, the communication is fine!
The program works with no exceptions and the data are send ok, from client to server.

更新:


这是我用来启用的代码段匿名密码(我已经为服务器和客户端部分做了这个):

UPDATE:
This is the snippet I use to enable the anon ciphers (I have done this for server and client part):

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) 

现在,如果我只是这样做:

Now if I simply do:

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)

谢谢

推荐答案

你是对的, * _anon _ * 密码用于完整的未经身份验证的连接(服务器和客户端都是匿名的)。使用这些密码套件无需证书。我写了一个小代码来测试:

You are right, *_anon_* ciphers are used for a complete unauthenticated connection (both server and client are anonymous). With these cipher suites no certificate is required. I wrote a small code to test:

ServerSocketFactory sf = SSLServerSocketFactory.getDefault();
final SSLServerSocket socket = (SSLServerSocket)sf.createServerSocket(443);
System.out.println(Arrays.toString(socket.getSupportedCipherSuites()));
System.out.println(Arrays.toString(socket.getEnabledCipherSuites()));

socket.setEnabledCipherSuites(new String[] {"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"});

Thread t = new Thread() {
    public void run() {
        try {
            Socket client = socket.accept();
            client.getOutputStream().write("Hello World\n".getBytes("ASCII"));
            client.close();
        } catch (IOException ioe) {
        }
    }
};

t.start();
Thread.sleep(2000);
SSLSocket client = (SSLSocket) SSLSocketFactory.getDefault().createSocket("localhost", 443);
client.setEnabledCipherSuites(new String[] {"SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA"});
InputStream in = client.getInputStream();
byte[] data = new byte[1024];
int len = in.read(data);
System.out.println(new String(data, 0, len));

我知道这段代码并不完美,但我成功地在客户端和服务器之间交换数据。可能您的服务器或客户端套接字配置不正确。你能给出你得到的完整堆栈跟踪吗?

I know that this code is not perfect but I successfully exchange data between the client and the server. Maybe your server or client socket is not well configured. Can you give the full stacktrace you got?

请注意,这些密码已被弃用,因为它们容易受到中间人攻击。

Note that these ciphers are deprecated since there are vulnerable to man-in-the-middle attacks.

更新:我发现了这个问题。 anonCipherSuitesSupported 数组长度太长。因此,在添加 * _ anon _ * 之后,数组以一堆 null 值结束。并且启用的密码列表中的实现似乎不接受 null

UPDATE : I found the issue. The anonCipherSuitesSupported array length is too long. Therefore after adding the *_anon_* the array is ending with a bunch of null values. And the implementation does not seem to accept null in the enabled cipher list.

String[] supported = server.getSupportedCipherSuites();
List<String> list= new ArrayList<String>();

for(int i = 0; i < supported.length; i++)
{
    if(supported[i].indexOf("_anon_") > 0)
    {
        list.add(supported[i]);
    }
}
String[] anonCipherSuitesSupported = list.toArray(new String[0]);

这篇关于java安全套接字没有认证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆