我试图通过SSL编写服务器/客户端通信,每一方都有自己的密钥库和证书,双方都需要相互验证。我自定义TrustManager以允许默认情况下验证不在信任库中的证书。我通过keytool生成密钥和证书。但是我首先在服务器端遇到了以下错误:
trigger seeding of SecureRandom
done seeding SecureRandom
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for SSLv2Hello
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 for TLSv1.1
[Raw read]: length = 5
0000: 16 03 01 00 6B ....k
[Raw read]: length = 107
0000: 01 00 00 67 03 01 55 F8 3A 82 11 AC ED 80 B3 32 ...g..U.:......2
0010: E4 0D 03 A2 21 2F 87 84 29 81 48 E7 98 0D 59 9A ....!/..).H...Y.
0020: 2D B7 D2 76 67 B2 00 00 2C C0 0A C0 14 00 35 C0 -..vg...,.....5.
0030: 05 C0 0F 00 39 00 38 C0 09 C0 13 00 2F C0 04 C0 ....9.8...../...
0040: 0E 00 33 00 32 C0 08 C0 12 00 0A C0 03 C0 0D 00 ..3.2...........
0050: 16 00 13 00 FF 01 00 00 12 00 0A 00 08 00 06 00 ................
0060: 17 00 18 00 19 00 0B 00 02 01 00 ...........
main, READ: TLSv1 Handshake, length = 107
*** ClientHello, TLSv1
RandomCookie: GMT: 1425553794 bytes = { 17, 172, 237, 128, 179, 50, 228, 13, 3, 162, 33, 47, 135, 132, 41, 129, 72, 231, 152, 13, 89, 154, 45, 183, 210, 118, 103, 178 }
Session ID: {}
Cipher Suites: [TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_RSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA, SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA, TLS_EMPTY_RENEGOTIATION_INFO_SCSV]
Compression Methods: { 0 }
Extension elliptic_curves, curve names: {secp256r1, secp384r1, secp521r1}
Extension ec_point_formats, formats: [uncompressed]
***
[read] MD5 and SHA1 hashes: len = 107
0000: 01 00 00 67 03 01 55 F8 3A 82 11 AC ED 80 B3 32 ...g..U.:......2
0010: E4 0D 03 A2 21 2F 87 84 29 81 48 E7 98 0D 59 9A ....!/..).H...Y.
0020: 2D B7 D2 76 67 B2 00 00 2C C0 0A C0 14 00 35 C0 -..vg...,.....5.
0030: 05 C0 0F 00 39 00 38 C0 09 C0 13 00 2F C0 04 C0 ....9.8...../...
0040: 0E 00 33 00 32 C0 08 C0 12 00 0A C0 03 C0 0D 00 ..3.2...........
0050: 16 00 13 00 FF 01 00 00 12 00 0A 00 08 00 06 00 ................
0060: 17 00 18 00 19 00 0B 00 02 01 00 ...........
%% Initialized: [Session-1, SSL_NULL_WITH_NULL_NULL]
%% Invalidated: [Session-1, SSL_NULL_WITH_NULL_NULL]
main, SEND TLSv1 ALERT: fatal, description = handshake_failure
main, WRITE: TLSv1 Alert, length = 2
[Raw write]: length = 7
0000: 15 03 01 00 02 02 28 ......(
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: no cipher suites in common
Exception in thread "main" javax.net.ssl.SSLHandshakeException: no cipher suites in common
at sun.security.ssl.Alerts.getSSLException(Alerts.java:192)
at sun.security.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1916)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:279)
at sun.security.ssl.Handshaker.fatalSE(Handshaker.java:269)
at sun.security.ssl.ServerHandshaker.chooseCipherSuite(ServerHandshaker.java:969)
at sun.security.ssl.ServerHandshaker.clientHello(ServerHandshaker.java:683)
at sun.security.ssl.ServerHandshaker.processMessage(ServerHandshaker.java:221)
at sun.security.ssl.Handshaker.processLoop(Handshaker.java:901)
at sun.security.ssl.Handshaker.process_record(Handshaker.java:837)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1035)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1344)
at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:901)
at sun.security.ssl.AppInputStream.read(AppInputStream.java:102)
at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:283)
at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:325)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:177)
at java.io.InputStreamReader.read(InputStreamReader.java:184)
at java.io.BufferedReader.fill(BufferedReader.java:154)
at java.io.BufferedReader.readLine(BufferedReader.java:317)
at java.io.BufferedReader.readLine(BufferedReader.java:382)
at ps.connection.SSLConnectionServer.doServerSide(SSLConnectionServer.java:49)
at ps.connection.SSLConnectionServer.main(SSLConnectionServer.java:64)
这是服务器端的代码:
KeyStore keyStore = KeyStore.getInstance("JKS");
String storeFile = pathToStores + "/" + keyStoreFile;
InputStream fileInput = new FileInputStream(storeFile);
keyStore.load(fileInput, passwd.toCharArray());
fileInput.close();
KeyManagerFactory keyManagerFac = KeyManagerFactory.getInstance("SunX509");
keyManagerFac.init(keyStore, passwd.toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLSv1");
String trustFile = pathToStores + "/" + trustStoreFile;
TrustManager [] trustManager = new TrustManager[]{new ReloadableX509TrustManager(trustFile, passwd)};
sslContext.init(keyManagerFac.getKeyManagers(), trustManager, null);
SSLServerSocketFactory sslssf = (SSLServerSocketFactory) SSLServerSocketFactory
.getDefault();
SSLServerSocket sslServerSocket = (SSLServerSocket) sslssf.createServerSocket(theServerPort);
sslServerSocket.setNeedClientAuth(false);
SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
String[] ciphers = sslSocket.getEnabledCipherSuites();
InputStream sslIn = sslSocket.getInputStream();
BufferedReader bufferReader = new BufferedReader(new InputStreamReader(sslIn));
String str = null;
while ((str = bufferReader.readLine()) != null){
System.out.println(str);
System.out.flush();
}
sslSocket.close();
以下是客户端的代码:
KeyStore keyStore = KeyStore.getInstance("JKS");
String keyFile = pathToStore + "/" + keyStoreFile;
InputStream keyInput = new FileInputStream(keyFile);
keyStore.load(keyInput, passwd.toCharArray());
keyInput.close();
KeyManagerFactory keyManagerFac = KeyManagerFactory.getInstance("SunX509");
keyManagerFac.init(keyStore, passwd.toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLSv1");
String trustFile = pathToStore + "/" + trustStoreFile;
TrustManager [] trustManager = new TrustManager[]{new ReloadableX509TrustManager(trustFile, passwd)};
sslContext.init(keyManagerFac.getKeyManagers(), trustManager, null);
SSLSocketFactory sslsf = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket) sslsf.createSocket(theServerName, theServerPort);
String[] ciphers = sslSocket.getEnabledCipherSuites();
sslSocket.addHandshakeCompletedListener(new HandShakeListener());
sslSocket.startHandshake();
OutputStream sslOut = sslSocket.getOutputStream();
sslOut.write("Hello RelayServer".getBytes());
sslOut.flush();
sslOut.close();
sslSocket.close();
我在Ubuntu上使用Oracle java 7。任何提示表示赞赏!
答案 0 :(得分:1)
使用密钥和信任存储初始化SSLContext
时,以后不会使用上下文。您使用了与上下文无关的SSL[Server]SocketFactory.getDefault()
。服务器失败,因为它没有指定密钥库。
尝试使用get[Server]SocketFactory()
中的SSLContext
方法。
另请阅读JSSE Guide