2013-04-11 2 views
3

STARTTLS를 사용하여 소켓을 SSLSocket으로 업그레이드하려고합니다. InspIRCd의 위키에서이 그것으로하고 startHandshake() 나는 항상 RECV 실패 얻을하지 않고,STARTTLS : recv를 사용하여 소켓을 SSLSocket으로 업그레이드하지 못했습니다.

else if (code.equals("670")) { 
    SSLSocketFactory sslSocketFactory = ((SSLSocketFactory) SSLSocketFactory.getDefault()); 
    SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(
         socket, 
         socket.getInetAddress().getHostAddress(), 
         socket.getPort(), 
         true); 
    sslSocket.startHandshake(); 
    bufferedReader = new BufferedReader(new InputStreamReader(sslSocket.getInputStream(), getEncoding())); 
    bufferedWriter = new BufferedWriter(new OutputStreamWriter(sslSocket.getOutputStream(), getEncoding())); 
    socket = sslSocket; 
} 

그러나

>> STARTTLS 
<< :test2.chatspike.net 670 nickname :STARTTLS successful, go ahead with TLS handshake 
(SSL Handshake) 

그래서 내 코드에 내가 쓴 (약간 단순화)을 작동하는데 어떻게 (난 그냥 그것을 얻을하지 않고 나는 새의 BufferedReader에서 (

0) -Djavax.net.debug=all

java.io.IOException: Can't connect to server 
    at org.pircbotx.PircBotX.connect(PircBotX.java:472) [Exception handling] 
    at org.pircbotx.PircBotX.connect(PircBotX.java:224) [Overridden constructor] 
    at org.pircbotx.impl.PircBotXExample.main(PircBotXExample.java:185) 
Caused by: java.net.SocketException: Software caused connection abort: recv failed 
    at java.net.SocketInputStream.read(SocketInputStream.java:150) 
    at java.net.SocketInputStream.read(SocketInputStream.java:121) 
    at sun.security.ssl.InputRecord.readFully(InputRecord.java:442) 
    at sun.security.ssl.InputRecord.read(InputRecord.java:480) 
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:927) 
    at sun.security.ssl.SSLSocketImpl.waitForClose(SSLSocketImpl.java:1707) 
    at sun.security.ssl.HandshakeOutStream.flush(HandshakeOutStream.java:122) 
    at sun.security.ssl.Handshaker.kickstart(Handshaker.java:909) 
    at sun.security.ssl.SSLSocketImpl.kickstartHandshake(SSLSocketImpl.java:1423) 
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1288) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1339) 
    at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1323) 
    at org.pircbotx.PircBotX.connect(PircBotX.java:411) [startHandshake line] 
    ... 2 more 

전체 로그를 읽으려고 할 때

1365707641940 <<<:kenny.chatspike.net 670 PircBotX :STARTTLS successful, go ahead with TLS handshake 
keyStore is : 
keyStore type is : jks 
keyStore provider is : 
init keystore 
init keymanager of type SunX509 
trustStore is: C:\Program Files\Java\jdk1.7.0_17\jre\lib\security\cacerts 
trustStore type is : jks 
trustStore provider is : 
init truststore 

[*SNIP* A bunch of adding trusted certificates] 

trigger seeding of SecureRandom 
done seeding SecureRandom 
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA 
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA 
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA 
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256 
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA 
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA 
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA 
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA 
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 
Allow unsafe renegotiation: false 
Allow legacy hello messages: true 
Is initial handshake: true 
Is secure renegotiation: false 
%% No cached client session 
*** ClientHello, TLSv1 
RandomCookie: GMT: 1365707642 bytes = { 219, 198, 250, 114, 173, 93, 144, 4, 231, 53, 192, 242, 141, 137, 219, 115, 48, 203, 218, 188, 51, 30, 184, 245, 182, 150, 132, 254 } 
Session ID: {} 
Cipher Suites: [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_RC4_128_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, SSL_RSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_RC4_128_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, SSL_RSA_WITH_RC4_128_MD5, TLS_EMPTY_RENEGOTIATION_INFO_SCSV] 
Compression Methods: { 0 } 
Extension elliptic_curves, curve names: {secp256r1, sect163k1, sect163r2, secp192r1, secp224r1, sect233k1, sect233r1, sect283k1, sect283r1, secp384r1, sect409k1, sect409r1, secp521r1, sect571k1, sect571r1, secp160k1, secp160r1, secp160r2, sect163r1, secp192k1, sect193r1, sect193r2, secp224k1, sect239k1, secp256k1} 
Extension ec_point_formats, formats: [uncompressed] 
*** 
[write] MD5 and SHA1 hashes: len = 149 
0000: 01 00 00 91 03 01 51 67 0B 7A DB C6 FA 72 AD 5D ......Qg.z...r.] 
0010: 90 04 E7 35 C0 F2 8D 89 DB 73 30 CB DA BC 33 1E ...5.....s0...3. 
0020: B8 F5 B6 96 84 FE 00 00 2A C0 09 C0 13 00 2F C0 ........*...../. 
0030: 04 C0 0E 00 33 00 32 C0 07 C0 11 00 05 C0 02 C0 ....3.2......... 
0040: 0C C0 08 C0 12 00 0A C0 03 C0 0D 00 16 00 13 00 ................ 
0050: 04 00 FF 01 00 00 3E 00 0A 00 34 00 32 00 17 00 ......>...4.2... 
0060: 01 00 03 00 13 00 15 00 06 00 07 00 09 00 0A 00 ................ 
0070: 18 00 0B 00 0C 00 19 00 0D 00 0E 00 0F 00 10 00 ................ 
0080: 11 00 02 00 12 00 04 00 05 00 14 00 08 00 16 00 ................ 
0090: 0B 00 02 01 00          ..... 
main, WRITE: TLSv1 Handshake, length = 149 
main, waiting for close_notify or alert: state 1 
main, Exception while waiting for close java.net.SocketException: Software caused connection abort: recv failed 
main, handling exception: java.net.SocketException: Software caused connection abort: recv failed 
main, SEND TLSv1 ALERT: fatal, description = unexpected_message 
    at java.net.SocketInputStream.socketRead0(Native Method) 
main, WRITE: TLSv1 Alert, length = 2 
main, Exception sending alert: java.net.SocketException: Software caused connection abort: socket write error 
main, called closeSocket() 
1365707642425 *** Disconnected. 

이 오류의 원인은 무엇입니까? 나는이 기능이 다른 클라이언트가 그것을 할 수 있기 때문에 작동하는지는 알지만, 단지 Java에서 어떻게 할 것인지를 알 수 없다.

어떤 제안이 있나?

답변

4

sslSocket이 핸드 셰이 킹하는 동안 일부 테스트를 수행했으며 socket에서 데이터를 수신 할 때이 오류가 발생했습니다. 이는 예를 들어 이 아닌 socket에 등록 (NICK/LOGIN 보내기)하는 경우에 발생할 수 있습니다. TLSSTART를 연결 한 후 서버에 첫 번째 명령을 작성하고 다른 것을 보내기 전에 670/691 코드를 기다립니다.

중동에 대한 예외를 생성하지 않는 다음과 아무 문제없이 악수하는 관리 :

public static void main(String[] args) throws Exception { 
    Socket socket = new Socket("irc.chatspike.net",6667); 
    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())); 
    String line; 
    writer.write("STARTTLS\r\n"); 
    writer.flush(); 
    while ((line = reader.readLine()) != null) { 
     if (line.contains(" 670 ")) { 
      SSLContext sc = SSLContext.getInstance("TLS"); 
      sc.init(null, new TrustManager[]{ 
        new X509TrustManager() { 
         public java.security.cert.X509Certificate[] getAcceptedIssuers() { 
          return null; 
         } 
         public void checkClientTrusted(
          java.security.cert.X509Certificate[] certs, String authType) { 
         } 
         public void checkServerTrusted(
          java.security.cert.X509Certificate[] certs, String authType) { 
         } 
        } 
       }, new java.security.SecureRandom()); 
      SSLSocketFactory sslSocketFactory = ((SSLSocketFactory) sc.getSocketFactory()); 
      SSLSocket sslSocket = (SSLSocket) sslSocketFactory.createSocket(
           socket, 
           socket.getInetAddress().getHostAddress(), 
           socket.getPort(), 
           true); 
      sslSocket.startHandshake(); 
     } 
    } 
+1

맨 처음 줄로 STARTTLS를 보내면 여전히 recv가 실패합니다. 흥미롭게도 새로운 스레드를 생성하여 버퍼링 된 일반 텍스트에서 읽음으로써 아무 것도 발생하지 않는지 확인하려면 "EOFException : SSL 피어가 올바르게 종료되지 않았습니다." – TheLQ

+0

@TheLQ 내 편집을 확인하고 코드를 직접 시험해보십시오. – ddmps

+0

많은 테스트를 거친 후에 문제는 STARTTLS와 670 라인을 수신하는 사이에 서버로 아무 것도 보내지 않는 것으로 밝혀졌습니다. 서버가 연결을 종료하게 만들었다 고 생각됩니다. 코드를 보내 주셔서 감사합니다. 자바에서 가능하다는 것을 증명 했으므로 포기하지 않았습니다. – TheLQ

1

여기서 문제는 일반 텍스트로는 STARTTLS 명령 후 SSL 핸드 셰이크가 아닌 다른 무언가를 보내는 것입니다 소켓. STARTTLS를 발행하고 승인 된 후에는 일반 텍스트 소켓의 사용을 중지해야합니다.