2017-06-29 158 views
0

美好的一天!我有一個簡單的聊天應用程序與websocket(STOMP)。 我已經配置了使用mutal auth的ssl連接。Websocket(spring)ssl連接(空鏈)

服務器端:

server.port=8443 
server.ssl.key-store=path/to/server.jks 
server.ssl.trust-store=path/to/trusted.jks 
server.ssl.key-store-password=22222222 
server.ssl.trust-store-password=22222222 
server.ssl.client-auth=need 

客戶端:

System.setProperty("javax.net.ssl.keyStore","path/to/client.jks"); 
System.setProperty("javax.net.ssl.keyStorePassword","22222222"); 
System.setProperty("javax.net.ssl.trustStore","path/to/trusted.jks"); 
System.setProperty("javax.net.ssl.trustStorePassword","22222222"); 

服務器trusted.jks和客戶端trusted.jks是相同的。

所以當我嘗試使用

-Djavax.net.debug=ssl 

,我有很多的輸出和一些奇怪的情況的連接 - 我可以看到兩個關鍵協議(?)。第一個好 -

trustStore is: /path/to/trusted.jks 

adding as trusted cert: 
    Subject: [email protected], CN=ca, OU=ca, O=ca, L=ca, ST=ca, C=RU 
    Issuer: [email protected], CN=ca, OU=ca, O=ca, L=ca, ST=ca, C=RU 
    Algorithm: RSA; Serial number: 0x9952f188496b2545 
    Valid from Wed Jun 28 15:39:04 MSK 2017 until Sat Jun 26 15:39:04 MSK 2027 

所以我的CA證書被添加爲可信。然後

*** ClientHello, TLSv1.2 
//ok 
*** ServerHello, TLSv1.2 
//ok 
*** Certificate chain 
//my localhost server cert 
*** 
Found trusted certificate: 

Version: V3 
Subject: [email protected], CN=ca, OU=ca, O=ca, L=ca, ST=ca, C=RU 
Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11 

所以我的客戶端找到了這個服務器證書的可信證書。

*** ECDH ServerKeyExchange 
//ok 
*** CertificateRequest 
Cert Types: RSA, DSS, ECDSA 
Supported Signature Algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA 
Cert Authorities: 

*** ServerHelloDone 

而且我能找到我的鎖鏈 - 據我所知

*** Certificate chain 
chain [0] = [ 
[ 
    Version: V3 
    Subject: [email protected], CN=client3, OU=client3, O=client3, L=client3, ST=client3, C=RU 
    Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11 

chain [1] = [ 
[ 
    Version: V3 
    Subject: [email protected], CN=ca, OU=ca, O=ca, L=ca, ST=ca, C=RU 
    Signature Algorithm: SHA256withRSA, OID = 1.2.840.113549.1.1.11 
*** ECDHClientKeyExchange 
*** CertificateVerify 
*** Finished 

- 這是確定的。 然後,我可以看到:

DEBUG org.springframework.web.client.RestTemplate - GET request for "https://localhost:8443/chat/info" resulted in 200 (null) 
DEBUG org.springframework.web.socket.sockjs.client.WebSocketTransport - Starting WebSocket session on wss://localhost:8443/chat/437/f6158d1ee84b4c53ba55a6810b2f92a8/websocket 
DEBUG org.springframework.web.socket.client.standard.StandardWebSocketClient - 
Connecting to wss://localhost:8443/chat/437/f6158d1ee84b4c53ba55a6810b2f92a8/websocket 

再次增加信任存儲證書等等,都是一樣的,但

*** CertificateRequest 
Cert Types: RSA, DSS, ECDSA 
Supported Signature Algorithms: SHA512withECDSA, SHA512withRSA, SHA384withECDSA, SHA384withRSA, SHA256withECDSA, SHA256withRSA, SHA256withDSA, SHA224withECDSA, SHA224withRSA, SHA224withDSA, SHA1withECDSA, SHA1withRSA, SHA1withDSA 
Cert Authorities: 
<[email protected], CN=ca, OU=ca, O=ca, L=ca, ST=ca, C=RU> 
*** ServerHelloDone 
Warning: no suitable certificate found - continuing without client authentication 
*** Certificate chain 
<Empty> 
*** 

所以服務器對我說

ttps-jsse-nio-8443-exec-9, fatal error: 42: null cert chain 
javax.net.ssl.SSLHandshakeException: null cert chain 

有什麼想法關於問題?如果需要,我可以在這裏發佈我的密鑰庫和客戶端實現。 謝謝你的幫助!

更新與捲曲輸出

env -i curl -E ./chain.pem --key ./client.key --cacert ca.crt --verbose --user test:test https://localhost:8443/ 

* Trying 127.0.0.1... 
* Connected to localhost (127.0.0.1) port 8443 (#0) 
* found 1 certificates in ca.crt 
* found 704 certificates in /etc/ssl/certs 
* ALPN, offering http/1.1 
* SSL connection using TLS1.2/ECDHE_RSA_AES_128_GCM_SHA256 
* server certificate verification OK 
* server certificate status verification SKIPPED 
* common name: localhost (matched) 
* server certificate expiration date OK 
* server certificate activation date OK 
* certificate public key: RSA 
* certificate version: #3 
* subject: 

C=RU,ST=localhost, 
L=localhost,O=localhost,OU=localhost, 
CN=localhost,[email protected] 
* start date: Wed, 28 Jun 2017 13:07:14 GMT 
* expire date: Thu, 28 Jun 2018 13:07:14 GMT 
* issuer: C=RU,ST=ca,L=ca,O=ca,OU=ca,CN=ca,[email protected] 
* compression: NULL 
* ALPN, server did not agree to a protocol 
* Server auth using Basic with user 'kitcpp' 
> GET/HTTP/1.1 
> Host: localhost:8443 
> Authorization: Basic a2l0Y3BwOmtpdGNwcA== 
> User-Agent: curl/7.47.0 
> Accept: */* 
> 
< HTTP/1.1 200 
< X-Content-Type-Options: nosniff 
< X-XSS-Protection: 1; mode=block 
< Cache-Control: no-cache, no-store, max-age=0, must-revalidate 
< Pragma: no-cache 
< Expires: 0 
< Strict-Transport-Security: max-age=31536000 ; includeSubDomains 
< X-Frame-Options: DENY 
< Set-Cookie: JSESSIONID=67BACDE78AF68627516075B29C987C86; Path=/; Secure; HttpOnly 
< Last-Modified: Wed, 28 Jun 2017 16:29:53 GMT 
< Accept-Ranges: bytes 
< Content-Type: text/html;charset=UTF-8 
< Content-Language: en-US 
< Content-Length: 6935 
< Date: Fri, 30 Jun 2017 09:30:02 GMT 
< 
<!DOCTYPE html> 
<html> 
<head> 
//and so on (my web chat page) 
+0

您是否嘗試將WebSockets從圖片中取出,並查看是否可以使用相互身份驗證建立HTTPS連接? –

+0

Andy Wilkinson,如果我可以這麼說的話 - 我將我的用戶證書安裝到chrome並通過Web客戶端連接到聊天。 – RedCollarPanda

+0

我不確定這是否回答我的問題。 「網絡客戶端」是什麼意思?爲了簡單起見,我會使用類似'curl'的東西來驗證相互身份驗證是否適用於HTTPS。這或者表明問題是非常重要的,或者它是WebSockets特有的。 –

回答

2

您正在使用Tomcat的WebSocket的客戶端。 Its documentation描述應該如何配置爲使用SSL:

當使用WebSocket的客戶端連接到安全的服務器終端,客戶端SSL配置由提供javax.websocket.ClientEndpointConfig的userProperties控制。下面的用戶屬性的支持:

  • org.apache.tomcat.websocket.SSL_CONTEXT
  • org.apache.tomcat.websocket.SSL_PROTOCOLS
  • org.apache.tomcat.websocket.SSL_TRUSTSTORE
  • org.apache.tomcat.websocket.SSL_TRUSTSTORE_PWD

...

如果org.apache.tomcat.websocket.SSL_CONTEXT屬性設置,則org.apache.tomcat.websocket.SSL_TRUSTSTOREorg.apache.tomcat.websocket.SSL_TRUSTSTORE_PWD屬性將被忽略。

您正在使用Spring的WebSocket,它正在爲您創建ClientEndpointConfig。要配置其用戶屬性,請在StandardWebSocketClient上設置它們,然後在創建ClientEndpointConfig時使用它們。例如,假設默認SSL上下文已足夠:

StandardWebSocketClient simpleWebSocketClient = 
     new StandardWebSocketClient(); 
Map<String, Object> userProperties = new HashMap<>(); 
userProperties.put("org.apache.tomcat.websocket.SSL_CONTEXT", SSLContext.getDefault()); 
simpleWebSocketClient.setUserProperties(userProperties); 
+0

非常感謝耐心和幫助!這工作! – RedCollarPanda