当前位置: 首页 > 面试题库 >

客户端使用自签名证书连接到SSL服务器

谯乐池
2023-03-14
问题内容

我完全被困在这里。我有一个Java客户端代码,需要使用自签名证书连接到SSL服务器。

当我在服务器端禁用SSLv2支持时, 才会 出现此问题。

    private static DefaultHttpClient createHttpClient(int port) {
    try {
        java.lang.System.setProperty(
                "sun.security.ssl.allowUnsafeRenegotiation", "true");

        // First create a trust manager that won't care.
        X509TrustManager trustManager = new X509TrustManager() {
            public void checkClientTrusted(X509Certificate[] chain,
                    String authType) throws CertificateException {
                // Don't do anything.
            }

            public void checkServerTrusted(X509Certificate[] chain,
                    String authType) throws CertificateException {
                // Don't do anything.
            }

            public X509Certificate[] getAcceptedIssuers() {
                return new java.security.cert.X509Certificate[0];
            }
        };

        // Now put the trust manager into an SSLContext.
        // Supported: SSL, SSLv2, SSLv3, TLS, TLSv1, TLSv1.1
        SSLContext sslContext = SSLContext.getInstance("SSLv3");
        sslContext.init(null, new TrustManager[] { trustManager },
                new SecureRandom());

        // Use the above SSLContext to create your socket factory
        // (I found trying to extend the factory a bit difficult due to a
        // call to createSocket with no arguments, a method which doesn't
        // exist anywhere I can find, but hey-ho).
        SSLSocketFactory sf = new SSLSocketFactory(sslContext);
        // Accept any hostname, so the self-signed certificates don't fail
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);

        // Register our new socket factory with the typical SSL port and the
        // correct protocol name.
        //Scheme httpsScheme = new Scheme("https", sf, port);
        SchemeRegistry schemeRegistry = new SchemeRegistry();
        schemeRegistry.register(new Scheme("https", sf, port));

        HttpParams params = new BasicHttpParams();
        ClientConnectionManager cm = new SingleClientConnManager(params,
                schemeRegistry);

        return new DefaultHttpClient(cm, params);
    } catch (Exception ex) {
        Log.error("ERROR Creating SSL Connection: " + ex.getMessage());

        return null;
    }
}

痕迹是

trigger seeding of SecureRandom
done seeding SecureRandom
keyStore is : 
keyStore type is : jks
keyStore provider is : 
init keystore
init keymanager of type SunX509
trustStore is: /usr/lib/jvm/java-6-openjdk/jre/lib/security/cacerts
trustStore type is : jks
trustStore provider is : 
init truststore
adding as trusted cert:
x
x
x

trigger seeding of SecureRandom
done seeding SecureRandom
2010-12-16 17:25:08,705 [DEBUG][gwt-log][ 5] Connecting: 1
Allow unsafe renegotiation: true
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
%% No cached client session
*** ClientHello, TLSv1
RandomCookie:  GMT: 1292516708 bytes = { 205, 187, 238, 65, 164, 126, 107, 173, 51, 124, 60, 146, 4, 127, 165, 246, 216, 181, 106, 72, 9, 214, 243, 64, 34, 117, 141, 76 }
Session ID:  {}
Cipher Suites: [SSL_RSA_WITH_RC4_128_MD5, SSL_RSA_WITH_RC4_128_SHA, TLS_RSA_WITH_AES_128_CBC_SHA, TLS_RSA_WITH_AES_256_CBC_SHA, TLS_ECDH_ECDSA_WITH_RC4_128_SHA, TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDH_RSA_WITH_RC4_128_SHA, TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_ECDSA_WITH_RC4_128_SHA, TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, TLS_ECDHE_RSA_WITH_RC4_128_SHA, TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_RSA_WITH_AES_128_CBC_SHA, TLS_DHE_RSA_WITH_AES_256_CBC_SHA, TLS_DHE_DSS_WITH_AES_128_CBC_SHA, TLS_DHE_DSS_WITH_AES_256_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, TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, TLS_ECDHE_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_DES_CBC_SHA, SSL_DHE_RSA_WITH_DES_CBC_SHA, SSL_DHE_DSS_WITH_DES_CBC_SHA, SSL_RSA_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, 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 = 177
0000: 01 00 00 AD 03 01 4D 0A   3D 64 CD BB EE 41 A4 7E  ......M.=d...A..
xxxxxxx
00B0: 00                                                 .
btpool0-0, WRITE: TLSv1 Handshake, length = 177
[write] MD5 and SHA1 hashes:  len = 173
0000: 01 03 01 00 84 00 00 00   20 00 00 04 01 00 80 00  ........ .......
xxxxxxx
00A0: F6 D8 B5 6A 48 09 D6 F3   40 22 75 8D 4C           ...jH...@"u.L
btpool0-0, WRITE: SSLv2 client hello message, length = 173
[Raw write]: length = 175
0000: 80 AD 01 03 01 00 84 00   00 00 20 00 00 04 01 00  .......... .....
xxxxxxx
00A0: 7F A5 F6 D8 B5 6A 48 09   D6 F3 40 22 75 8D 4C     .....jH...@"u.L
btpool0-0, handling exception: java.net.SocketException: Connection reset
btpool0-0, SEND TLSv1 ALERT:  fatal, description = unexpected_message
btpool0-0, WRITE: TLSv1 Alert, length = 2
btpool0-0, Exception sending alert: java.net.SocketException: Broken pipe
btpool0-0, called closeSocket()
btpool0-0, IOException in getSession():  java.net.SocketException: Connection reset
2010-12-16 17:25:08,890 [DEBUG][gwt-log][ 6] peer not authenticated
javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated
    at sun.security.ssl.SSLSessionImpl.getPeerCertificates(SSLSessionImpl.java:371)
    at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:128)
    at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:399)
    at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:143)
    at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:149)
    at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:108)
    at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:415)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:641)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:731)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:709)
    at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:700)

[Fatal Error] :1:1: Premature end of file.
Finalizer, called close()
Finalizer, called closeInternal(true)

在服务器端,我可以看到以下跟踪:

info sock48 handshake start {before/accept initialization}
info sock48 accept loop {before/accept initialization}
info sock48 accept exit {SSLv3 read client hello B}
error sock48 {wrong version number}

如果启用SSL2,我会看到

info sock47 handshake start {before/accept initialization}
info sock47 accept loop {before/accept initialization}
info sock47 accept loop {SSLv3 read client hello A}
info sock47 accept loop {SSLv3 write server hello A}
info sock47 accept loop {SSLv3 write certificate A}
info sock47 accept loop {SSLv3 write server done A}
info sock47 accept loop {SSLv3 flush data}
info sock47 accept exit {SSLv3 read client certificate A}
info sock47 accept exit {SSLv3 read client certificate A}
info sock47 accept loop {SSLv3 read client key exchange A}
info sock47 accept loop {SSLv3 read finished A}
info sock47 accept loop {SSLv3 write change cipher spec A}
info sock47 accept loop {SSLv3 write finished A}
info sock47 accept loop {SSLv3 flush data}
info sock47 handshake done {SSL negotiation finished successfully}
info sock47 accept exit {SSL negotiation finished successfully}
info sock47 alert write {close notify}

而且一切正常。

我还知道那不是服务器端的东西,因为与其他软件连接可以正常工作。

知道我在做什么错吗?

还有人知道这个“读取客户端问候A / B”是什么意思吗?

谢谢

更新-已修复

需要使用此新的TLSSocketFactory替换SSLSocketFactory。

public class TLSSocketFactory extends SSLSocketFactory {

private final javax.net.ssl.SSLSocketFactory socketfactory;

public TLSSocketFactory(SSLContext sslContext) {
    super(sslContext);

    this.socketfactory = sslContext.getSocketFactory();
}

public Socket createSocket() throws IOException {
    SSLSocket socket = (SSLSocket) super.createSocket();

    socket.setEnabledProtocols(new String[] {"SSLv3, TLSv1"});

    return socket;
}

public Socket createSocket(
        final Socket socket,
        final String host,
        final int port,
        final boolean autoClose
    ) throws IOException, UnknownHostException {

    SSLSocket sslSocket = (SSLSocket) this.socketfactory.createSocket(
            socket,
            host,
            port,
            autoClose
      );

    sslSocket.setEnabledProtocols(new String[] {"SSLv3", "TLSv1"});

    getHostnameVerifier().verify(host, sslSocket);

    return sslSocket;
}

}


问题答案:

从客户端上已启用的协议列表中删除SSLv2ClientHello。



 类似资料:
  • 问题内容: 它看起来像一个标准问题,但是我在任何地方都找不到清晰的方向。 我有Java代码试图连接到可能带有自签名(或过期)证书的服务器。该代码报告以下错误: 据我了解,我必须使用keytool并告诉java允许这种连接是可以的。 解决此问题的所有说明均假定我完全精通keytool,例如 生成服务器的私钥并将其导入密钥库 是否有人可以发布详细说明? 我正在运行Unix,所以bash脚本是最好的。

  • 问题内容: 我正在连接到以前成功使用过的Web服务,但是现在他们已经更改了主机名并向我发送了两个.pem文件。一个是CA,另一个是我的新客户证书。 (我将Java 1.5,Spring + Spring Web Services与Apache httpclient一起使用,但是我怀疑我的问题是证书,密钥和SSL本身。) 我已经导入了.pem文件以及从Firefox导出到cacerts中的主机的.c

  • 问题内容: 我在使用自签名证书连接到mqtt服务器时遇到问题。即时通讯使用Paho客户端,并想使用连接到服务器。实际上,我成功连接了Android API 20+,但此版本以下没有成功。 香港专业教育学院到目前为止做了什么: 1-创建了PKCS#12密钥库,并将.crt文件放入密码并为其添加密码并将其保存(它将是.pfx文件) 2-将.pfx文件添加到android项目中资源的原始文件夹中 3-使

  • 问题内容: 我正在使用Jersey客户端库针对在jboss上运行的rest服务运行测试。我使用自签名证书在服务器(在本地主机上运行)上设置了https。 但是,每当我使用https url运行测试时,都会出现以下错误: 我知道这是因为我的自签名证书不在Java密钥库中。有什么办法可以让我不检查ssl证书的有效性,而直接使用它呢? 这段代码只能在测试服务器上运行,因此,我不想在每次设置新的测试服务器

  • 我需要创建web服务客户端,这家提供服务的公司向我们发送wsdl文件。我有wsdl文件、用户名和密码、服务url和txt文件,其中包含一些密钥,比如“20A9 38 4e 82 3a 94 d1…”。服务器有自签名证书,我试图通过InstallCert获取证书。java,使用keytool等生成密钥库。当我使用axis2 wsdl2java从wsdl生成客户端时,它会生成客户端,但在生成过程结束时

  • websocket客户端(使用Autobahn/Python和Twisted)需要连接到websocket服务器:客户端需要向服务器提供其客户端证书,客户端需要检查服务器的证书。例如,这些证书是在Kubernetes minikube安装过程中创建的。特别地: 服务器证书(据我所知为X509格式) 客户端证书~/。minikube/客户。按键 我已经检查过,我可以成功地使用这些证书密钥使用发出库伯