繁体   English   中英

如何在Java SE中使用SSL设置相互身份验证

[英]How to set mutual authentication using SSL in Java SE

我是第一次在Java中使用SSL,试图创建一个echo服务器。 当只有服务器需要进行身份验证时,我设法让它工作(在设置属性指向适当的KeyStore和TrustStore之后):

服务器端:

    SSLServerSocketFactory serverSocketFactory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
    SSLServerSocket serverSocket = (SSLServerSocket) serverSocketFactory.createServerSocket(bancoPort);
    String [] supported = serverSocketFactory.getSupportedCipherSuites();
    serverSocket.setEnabledCipherSuites(supported);
    serverSocket.setEnabledProtocols(new String[]{"TLSv1"});
    SSLSocket s = (SSLSocket) serverSocket.accept();

客户端:

SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket bancoSocket = (SSLSocket) socketFactory.createSocket(bancoIP, bancoPort);
String[] suites = bancoSocket.getSupportedCipherSuites();
bancoSocket.setEnabledCipherSuites(suites);

由于调试模式,我知道用于身份验证的密码套件是TLS_ECDH_anon_WITH_AES_128_CBC_SHA:

main, READ: TLSv1 Handshake, length = 215
*** ClientHello, TLSv1
RandomCookie:  GMT: 1399451465 bytes = { 177, 86, 70, 228, 7, 0, 109, 56, 245, 8, 243, 18, 122, 186, 159, 138, 76, 99, 65, 224, 21, 100, 1, 90, 20, 109, 241, 216 }
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, TLS_ECDH_anon_WITH_AES_128_CBC_SHA, TLS_DH_anon_WITH_AES_128_CBC_SHA, TLS_ECDH_anon_WITH_RC4_128_SHA, SSL_DH_anon_WITH_RC4_128_MD5, TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA, SSL_DH_anon_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_ECDSA_WITH_NULL_SHA, TLS_ECDHE_RSA_WITH_NULL_SHA, SSL_RSA_WITH_NULL_SHA, TLS_ECDH_ECDSA_WITH_NULL_SHA, TLS_ECDH_RSA_WITH_NULL_SHA, TLS_ECDH_anon_WITH_NULL_SHA, SSL_RSA_WITH_NULL_MD5, SSL_RSA_WITH_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_DH_anon_WITH_DES_CBC_SHA, SSL_RSA_EXPORT_WITH_RC4_40_MD5, SSL_DH_anon_EXPORT_WITH_RC4_40_MD5, SSL_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA, SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA, SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA, TLS_KRB5_WITH_RC4_128_SHA, TLS_KRB5_WITH_RC4_128_MD5, TLS_KRB5_WITH_3DES_EDE_CBC_SHA, TLS_KRB5_WITH_3DES_EDE_CBC_MD5, TLS_KRB5_WITH_DES_CBC_SHA, TLS_KRB5_WITH_DES_CBC_MD5, TLS_KRB5_EXPORT_WITH_RC4_40_SHA, TLS_KRB5_EXPORT_WITH_RC4_40_MD5, TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA, TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5]
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]
***
%% Initialized:  [Session-1, SSL_NULL_WITH_NULL_NULL]
%% Negotiating:  [Session-1, TLS_ECDH_anon_WITH_AES_128_CBC_SHA]
*** ServerHello, TLSv1
RandomCookie:  GMT: 1399451466 bytes = { 252, 63, 206, 222, 115, 40, 143, 4, 55, 11, 88, 196, 5, 10, 114, 159, 76, 144, 181, 27, 73, 248, 196, 71, 169, 136, 228, 82 }
Session ID:  {83, 106, 239, 74, 65, 85, 23, 110, 97, 151, 196, 61, 224, 79, 140, 15, 11, 132, 208, 66, 112, 216, 122, 85, 27, 159, 194, 255, 104, 171, 81, 220}
Cipher Suite: TLS_ECDH_anon_WITH_AES_128_CBC_SHA
Compression Method: 0
Extension renegotiation_info, renegotiated_connection: <empty>
***
Cipher suite:  TLS_ECDH_anon_WITH_AES_128_CBC_SHA

如果我添加到服务器代码行

serverSocket.setNeedClientAuth(true);

一切都崩溃了。 然后使用的套件是TLS_KRB5_WITH_RC4_128_MD5,但是客户端显然没有准备好使用Kerberos,因为这是在发送第一条要回显的消息时在客户端弹出的错误:

may 08, 2014 3:31:30 AM echoclient.EchoClientSSL main
Grave: null
java.io.IOException: Invalid service principal name: host/desk-linux
    at sun.security.ssl.krb5.KerberosClientKeyExchangeImpl.getServiceTicket(KerberosClientKeyExchangeImpl.java:307)
    at sun.security.ssl.krb5.KerberosClientKeyExchangeImpl.init(KerberosClientKeyExchangeImpl.java:112)
    at sun.security.ssl.KerberosClientKeyExchange.init(KerberosClientKeyExchange.java:122)
    at sun.security.ssl.KerberosClientKeyExchange.<init>(KerberosClientKeyExchange.java:80)
    at sun.security.ssl.ClientHandshaker.serverHelloDone(ClientHandshaker.java:873)
    at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:285)
    at sun.security.ssl.Handshaker.processLoop(Handshaker.java:868)
    at sun.security.ssl.Handshaker.process_record(Handshaker.java:804)
    at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1016)
    at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1312)
    at sun.security.ssl.SSLSocketImpl.writeRecord(SSLSocketImpl.java:702)
    at sun.security.ssl.AppOutputStream.write(AppOutputStream.java:122)
    at java.io.DataOutputStream.write(DataOutputStream.java:107)
    at java.io.DataOutputStream.writeUTF(DataOutputStream.java:401)
    at java.io.DataOutputStream.writeUTF(DataOutputStream.java:323)
    at echoclient.EchoClientSSL.main(EchoClientSSL.java:45)
Caused by: KrbException: Cannot locate default realm
    at sun.security.krb5.PrincipalName.<init>(PrincipalName.java:367)
    at sun.security.ssl.krb5.KerberosClientKeyExchangeImpl.getServiceTicket(KerberosClientKeyExchangeImpl.java:302)
    ... 15 more
Caused by: KrbException: Cannot locate default realm
    at sun.security.krb5.Config.getDefaultRealm(Config.java:1181)
    at sun.security.krb5.PrincipalName.<init>(PrincipalName.java:365)
    ... 16 more
Caused by: KrbException: Generic error (description in e-text) (60) - Unable to locate Kerberos realm
    at sun.security.krb5.Config.getRealmFromDNS(Config.java:1277)
    at sun.security.krb5.Config.getDefaultRealm(Config.java:1162)
    ... 17 more

我试图在客户端中将setEnabledCipherSuite设置为我认识的工作(TLS_ECDH_anon_WITH_AES_128_CBC_SHA),而不是整个允许的密码套件,但如果我这样做,我在服务器上获得异常“javax.net.ssl.SSLHandshakeException:no cipher共同的套房“。 日志:

main, READ: TLSv1 Handshake, length = 114
*** ClientHello, TLSv1
RandomCookie:  GMT: 1399451199 bytes = { 43, 248, 163, 155, 250, 241, 124, 194, 33, 46, 197, 27, 122, 1, 148, 254, 255, 71, 219, 220, 213, 91, 180, 178, 126, 242, 166, 82 }
Session ID:  {}
Cipher Suites: [TLS_ECDH_anon_WITH_AES_128_CBC_SHA]
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]
Extension renegotiation_info, renegotiated_connection: <empty>
***
%% 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
main, called closeSocket()
main, handling exception: javax.net.ssl.SSLHandshakeException: no cipher suites in common
may 08, 2014 3:38:56 AM echoserver.EchoServerSSL main
Grave: null
javax.net.ssl.SSLHandshakeException: no cipher suites in common

服务器和客户端都在同一台机器上运行,因此我不知道在尝试验证客户端时,用于验证服务器的密码套件是如何失败的。

String [] supported = serverSocketFactory.getSupportedCipherSuites();
serverSocket.setEnabledCipherSuites(supported);

String[] suites = bancoSocket.getSupportedCipherSuites();
bancoSocket.setEnabledCipherSuites(suites);

不要乱用启用的密码套件。 取出代码并重新测试。 您已经启用了匿名套件,在这两个套件中,任何方向都没有任何身份验证。

Cipher Suites: [TLS_ECDH_anon_WITH_AES_128_CBC_SHA]

正如@EJP所说,这些线路适得其反,需要将其删除。 问题不在于代码,而在于如何创建密钥库和信任库中的证书。

一旦我按照这里的说明一切正常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM