Java,通过SSL连接时出错(握手期间远程主机关闭连接)

时间:2014-07-22 11:13:17

标签: java android ssl

大家。 我需要使用服务器和客户端证书连接到服务器。我使用以下代码: (移植形式的android)

private HttpsURLConnection getHttpsURLConnection(URL url, String certAlias)
        throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException, UnrecoverableKeyException, java.security.cert.CertificateException {
    HttpsURLConnection connection = null;
    CertificateFactory certFactory = null;
    java.security.cert.Certificate cert = null;
    KeyStore keyStore = null;
    TrustManagerFactory tmFactory = null;
    SSLContext sslContext = null;

    //load client cert
    final KeyStore clientKS = getClientKeyStore();
    KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
    kmf.init(keyStore, clientCertificatePassword.toCharArray());

    // Load certificates from an InputStream
    certFactory = CertificateFactory.getInstance("X.509");

    InputStream servCertIS = new FileInputStream(caCertificateName);
    cert = certFactory.generateCertificate(servCertIS);

    // Create a KeyStore containing the trusted certificates
    keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
    keyStore.load(null, null);
    keyStore.setCertificateEntry(certAlias, cert);

    // Create a TrustManager that trusts the certificates in our KeyStore
    tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    tmFactory.init(keyStore);
    // Create an SSLContext that uses our TrustManager
    sslContext = SSLContext.getInstance("TLS");

    sslContext.init(kmf.getKeyManagers(), tmFactory.getTrustManagers(), null);

    connection = (HttpsURLConnection)url.openConnection();
    connection.setSSLSocketFactory(sslContext.getSocketFactory());
    InputStream in = connection.getInputStream(); //error!
    //peoccess inputStream here.

    return connection;

我已经为ssl和握手启用了调试属性,并获得了以下输出:

*** ServerHelloDone
*** Certificate chain
***
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
main, WRITE: TLSv1 Handshake, length = 269
SESSION KEYGEN:
PreMaster Secret:
CONNECTION KEYGEN:
Client Nonce:
Server Nonce:
Master Secret:
Client MAC write Secret:
Server MAC write Secret:
Client write key:
Server write key:
Client write IV:
Server write IV:

main, WRITE: TLSv1 Change Cipher Spec, length = 1
*** Finished
verify_data:  { 104, 160, 185, 140, 237, 61, 94, 119, 119, 68, 101, 52 }
***
main, WRITE: TLSv1 Handshake, length = 48
main, received EOFException: error
main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
%% Invalidated:  [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA]
main, SEND TLSv1 ALERT:  fatal, description = handshake_failure
main, WRITE: TLSv1 Alert, length = 32
main, called closeSocket()
javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
    at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(Unknown Source)
    at testClient1.getHttpsURLConnection(testClient1.java:86)
    at testClient1.getClient(testClient1.java:106)
    at testClient1.main(testClient1.java:134)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
    at sun.security.ssl.InputRecord.read(Unknown Source)
    ... 11 more

我在Android设备和桌面java上收到此错误。但我可以使用此客户端证书随时通过webbrowser连接到服务器。

也许它很重要 服务器的URL是:https://icon.sbrf.ru:9443(注意端口) 客户证书也带有西里尔字母(我不知道是不是这个问题,但西里尔符号经常出现问题)。

更新

这是CertificateRequest

    *** CertificateRequest
Cert Types: RSA, DSS, ECDSA
Cert Authorities:
<CN=ICONDP, OU=00CA, O=Savings Bank of the Russian Federation, L=RU, ST=Moscow>
<CN=SberBank External CA, O=sberbank, C=ru>
<CN=icon.sbrf.ru, OU=00CA, O=Savings Bank of the Russian Federation, C=RU>
<CN=Sberbank Enterprise CA, O=Sberbank, C=RU>
<CN=tv-icon01.sigma.sbrf.ru, OU=00CA, O=Savings Bank of the Russian Federation, C=RU>
<CN=TV-ICON01.sigma.sbrf.ru, OU=Root Certificate, OU=TV-ICON01Cell01, OU=TV-ICON01CellManager01, O=IBM, C=US>
<CN=Sberbank Root CA, O=Sberbank, C=RU>
<CN=Sberbank Test CA, O=Sberbank, C=RU>
*** ServerHelloDone
*** Certificate chain
***
*** ClientKeyExchange, RSA PreMasterSecret, TLSv1
main, WRITE: TLSv1 Handshake, length = 269
SESSION KEYGEN:
PreMaster Secret:
0000: 03 01 AC CE 4B 71 A4 A6   45 94 75 D8 B5 80 AE DA  ....Kq..E.u.....
0010: D3 01 0D 6F FA 1F 6F E4   F8 4C 47 7A EE 48 A6 02  ...o..o..LGz.H..
0020: 21 9F 79 6E 61 AE B0 DA   29 F0 97 B4 FD 0A 41 88  !.yna...).....A.
CONNECTION KEYGEN:
Client Nonce:
0000: 53 D6 17 36 80 81 C3 3B   16 E5 60 3E 29 B3 86 68  S..6...;..`>)..h
0010: F2 CA 49 13 87 19 98 A0   0C 88 88 FE 03 95 F6 91  ..I.............
Server Nonce:
0000: 53 D6 17 31 BA B0 DB E0   0A E2 7E 07 CF 04 C9 F9  S..1............
0010: 17 EA F1 F6 A5 C3 20 50   8D 3C 72 8F 42 57 DF 51  ...... P.<r.BW.Q
Master Secret:
0000: 92 49 CF 65 F3 64 26 CF   54 5F 78 2F 83 4E D2 4A  .I.e.d&.T_x/.N.J
0010: 20 E0 E0 AE CC 5F F8 6B   09 4E 2F E6 A8 01 94 10   ...._.k.N/.....
0020: 35 7B BD 2B A7 43 2E D2   4C 0F B1 F6 3C 6B 1E 08  5..+.C..L...<k..
Client MAC write Secret:
0000: 87 04 6A 37 DD 7F B6 D6   AA 31 FE 10 C8 0E B0 71  ..j7.....1.....q
0010: 16 6F 72 AF                                        .or.
Server MAC write Secret:
0000: C7 64 75 F7 E2 67 2C 8F   DF 14 6C 5E 7E 01 8A C1  .du..g,...l^....
0010: A0 8B E4 C4                                        ....
Client write key:
0000: 3E CE F3 FC B1 B0 C7 E2   6C F1 20 68 36 39 A5 E5  >.......l. h69..
Server write key:
0000: 26 C8 9F 98 DE 58 D3 0E   A1 25 38 05 4E E7 25 DF  &....X...%8.N.%.
Client write IV:
0000: 0C CE 33 F3 1C 00 C1 5B   3F 75 F7 EF EB AA 16 69  ..3....[?u.....i
Server write IV:
0000: 1A 18 D6 B1 32 23 5D 26   24 26 96 BC 42 1F 27 A2  ....2#]&$&..B.'.
main, WRITE: TLSv1 Change Cipher Spec, length = 1
*** Finished
verify_data:  { 228, 62, 93, 239, 222, 236, 155, 56, 146, 50, 189, 117 }
***
main, WRITE: TLSv1 Handshake, length = 48
main, received EOFException: error
main, handling exception: javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
%% Invalidated:  [Session-1, TLS_RSA_WITH_AES_128_CBC_SHA]
main, SEND TLSv1 ALERT:  fatal, description = handshake_failure
main, WRITE: TLSv1 Alert, length = 32
main, called closeSocket()

证书链真的是空的,我无法理解为什么,因为我使用100%工作的客户端证书(我通过webbrowser检查过)。

还有很多其他信息,包括此记录之前的日志文件中的证书链,但我相信它们都与服务器证书有关。

所以,问题似乎是证书加载代码中的某个地方,但我不知道在哪里

更新2

所以,我已经创建了一个kesytore并导入客户端证书,然后将其转换为jks。 这是 keytool -list -keystore test.jks -v

的结果
Keystore type: JKS
Keystore provider: SUN

Your keystore contains 2 entries

Alias name: lp-32205b37-88a0-4d85-8c6a-4a18daa82dd0
Creation date: 28.07.2014
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: EMAILADDRESS=RONovoselov.SBT@sberbank.ru, CN=Новоселов Роман Олегович, OU=CA_Users, OU=CA, DC=sigma, DC=sbrf, DC=ru
Issuer: CN=SberBank External CA, O=sberbank, C=ru
Serial number: 4ccbdc23000000002851
Valid from: Wed Mar 07 16:55:00 MSK 2012 until: Fri Mar 07 17:05:00 MSK 2014
Certificate fingerprints:
     MD5:  A0:6F:EA:C6:16:34:8D:46:67:26:21:E0:C6:28:BC:63
     SHA1: 19:77:D8:62:44:49:08:89:0E:42:60:8E:64:D2:97:18:36:B5:BA:2D
     SHA256: D0:CF:86:FD:46:0F:29:E7:4A:26:AE:D5:63:5B:C8:41:1E:A8:D3:13:9E:EC:0D:BA:C6:8D:B1:D4:4D:21:2B:45
     Signature algorithm name: SHA1withRSA
     Version: 3

Extensions: 

#1: ObjectId: 1.2.840.113549.1.9.15 Criticality=false
0000: 30 35 30 0E 06 08 2A 86   48 86 F7 0D 03 02 02 02  050...*.H.......
0010: 00 80 30 0E 06 08 2A 86   48 86 F7 0D 03 04 02 02  ..0...*.H.......
0020: 00 80 30 07 06 05 2B 0E   03 02 07 30 0A 06 08 2A  ..0...+....0...*
0030: 86 48 86 F7 0D 03 07                               .H.....


#2: ObjectId: 1.3.6.1.4.1.311.21.10 Criticality=false
0000: 30 18 30 0A 06 08 2B 06   01 05 05 07 03 04 30 0A  0.0...+.......0.
0010: 06 08 2B 06 01 05 05 07   03 02                    ..+.......


#3: ObjectId: 1.3.6.1.4.1.311.21.7 Criticality=false
0000: 30 2F 06 27 2B 06 01 04   01 82 37 15 08 84 F3 D1  0/.'+.....7.....
0010: 3C 87 F2 87 61 87 BD 9B   02 83 AA B4 63 81 82 FA  <...a.......c...
0020: 35 81 2A 84 FB D4 1C 83   BD CB 49 02 01 64 02 01  5.*.......I..d..
0030: 17                                                 .


#4: ObjectId: 1.3.6.1.5.5.7.1.1 Criticality=false
AuthorityInfoAccess [
  [
   accessMethod: ocsp
   accessLocation: URIName: http://pki.sberbank.ru/pki/aia/Cert01.sigma.sbrf.ru_SberBank%20External%20CA.crt
, 
   accessMethod: caIssuers
   accessLocation: URIName: ldap:///CN=SberBank%20External%20CA,CN=AIA,CN=Public%20Key%20Services,CN=Services,CN=Configuration,DC=sigma,DC=sbrf,DC=ru?cACertificate?base?objectClass=certificationAuthority
, 
   accessMethod: ocsp
   accessLocation: URIName: http://extpki.sigma.sbrf.ru/CertEnroll/Cert01.sigma.sbrf.ru_SberBank%20External%20CA.crt
]
]

#5: ObjectId: 2.5.29.35 Criticality=false
AuthorityKeyIdentifier [
KeyIdentifier [
0000: DB F3 38 88 08 D3 25 A2   D6 3E 5A C2 28 6D 21 09  ..8...%..>Z.(m!.
0010: E7 2E 1E B3                                        ....
]
]

#6: ObjectId: 2.5.29.31 Criticality=false
CRLDistributionPoints [
  [DistributionPoint:
     [URIName: http://pki.sberbank.ru/pki/cdp/SberBank%20External%20CA.crl, URIName: ldap:///CN=SberBank%20External%20CA,CN=Cert01,CN=CDP,CN=Public%20Key%20Services,CN=Services,CN=Configuration,DC=sigma,DC=sbrf,DC=ru?certificateRevocationList?base?objectClass=cRLDistributionPoint, URIName: http://extpki.sigma.sbrf.ru/CertEnroll/SberBank%20External%20CA.crl]
]]

#7: ObjectId: 2.5.29.37 Criticality=false
ExtendedKeyUsages [
  emailProtection
  clientAuth
]

#8: ObjectId: 2.5.29.15 Criticality=false
KeyUsage [
  DigitalSignature
  Key_Encipherment
]

#9: ObjectId: 2.5.29.17 Criticality=false
SubjectAlternativeName [
  Other-Name: Unrecognized ObjectIdentifier: 1.3.6.1.4.1.311.20.2.3
  RFC822Name: RONovoselov.SBT@sberbank.ru
]

#10: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 4C AB B5 F4 9B 7D FB 50   73 E0 CF EB AC 3D 00 5F  L......Ps....=._
0010: FE 82 32 9F                                        ..2.
]
]



*******************************************
*******************************************


Alias name: test
Creation date: 28.07.2014
Entry type: PrivateKeyEntry
Certificate chain length: 1
Certificate[1]:
Owner: CN=Aleksey Makarkin, OU=SBRF, O=SBRF, L=Moscow, ST=Moscow, C=RU
Issuer: CN=Aleksey Makarkin, OU=SBRF, O=SBRF, L=Moscow, ST=Moscow, C=RU
Serial number: 7f98a299
Valid from: Mon Jul 28 15:10:33 MSK 2014 until: Sun Oct 26 15:10:33 MSK 2014
Certificate fingerprints:
     MD5:  BC:51:FA:3B:6A:EB:4A:40:BC:87:53:DB:6D:E5:D7:59
     SHA1: 74:6B:08:92:0C:8D:57:34:CF:18:EC:6D:60:70:07:C2:07:E5:C5:00
     SHA256: DD:4D:C7:3E:0C:4F:25:1B:6F:07:76:98:C2:B4:C8:5D:C9:A8:9D:87:E5:8D:AE:12:26:8C:22:0C:89:1D:E3:02
     Signature algorithm name: SHA1withDSA
     Version: 3

Extensions: 

#1: ObjectId: 2.5.29.14 Criticality=false
SubjectKeyIdentifier [
KeyIdentifier [
0000: 06 F5 F7 A7 83 44 FC 9C   F2 70 6B EC 04 E8 03 3E  .....D...pk....>
0010: C4 B5 A0 FC                                        ....
]
]



*******************************************
*******************************************

2 个答案:

答案 0 :(得分:1)

服务器要求提供客户端证书但您没有发送一个,因此它关闭了连接。

您根本没有客户端证书,或者至少您没有服务器信任的证书。在跟踪开始之前,您可以立即在CertificateRequest消息中看到服务器信任的签名者。

答案 1 :(得分:0)

最后我解决了这个问题。

起初我的代码中有一个愚蠢的错误

final KeyStore clientKS = getClientKeyStore(); //save client certificate in one keyStore
...
kmf.init(keyStore, clientCertificatePassword.toCharArray()); //load into another( use if for server certificate lately)

第二,似乎我正在使用的证书已被弃用

Valid from: Wed Mar 07 16:55:00 MSK 2012 until: Fri Mar 07 17:05:00 MSK 2014

出于某种原因,Chrome网络浏览器忽略了这一点,但是JVM(?) - 不是。我不知道怎么可能,但这是观察到的行为。

感谢@EJP的支持