Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ssl/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java HTTPS:SSLPeerUnverifiedException的HttpGet_Java_Ssl_Https_Httpclient - Fatal编程技术网

Java HTTPS:SSLPeerUnverifiedException的HttpGet

Java HTTPS:SSLPeerUnverifiedException的HttpGet,java,ssl,https,httpclient,Java,Ssl,Https,Httpclient,使用,我在尝试通过HTTPS进行通信时收到以下错误: 线程“main”javax.net.ssl.SSLPeerUnverifiedException中的异常:对等未经身份验证 这是我的密码: URI loginUri = new URI("https://myUrl.asp"); HttpClient httpclient = new DefaultHttpClient(); HttpGet httpget = new HttpGet( loginUri ); HttpResponse re

使用,我在尝试通过HTTPS进行通信时收到以下错误:

线程“main”javax.net.ssl.SSLPeerUnverifiedException中的异常:对等未经身份验证

这是我的密码:

URI loginUri = new URI("https://myUrl.asp");

HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet( loginUri );
HttpResponse response = httpclient.execute( httpget );

如何抑制或删除此错误?

使用HttpClient 3.x,您需要执行以下操作:

Protocol easyHttps = new Protocol("https", new EasySSLProtocolSocketFactory(), 443);
Protocol.registerProtocol("https", easyHttps);

可以找到EasySSLProtocolSocketFactory的实现。

注意:不要在生产代码中执行此操作,而是使用http,或者使用上面建议的实际自签名公钥

在HttpClient 4.xx上:

import static org.junit.Assert.assertEquals;

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.impl.client.DefaultHttpClient;
import org.junit.Test;

public class HttpClientTrustingAllCertsTest {

    @Test
    public void shouldAcceptUnsafeCerts() throws Exception {
        DefaultHttpClient httpclient = httpClientTrustingAllSSLCerts();
        HttpGet httpGet = new HttpGet("https://host_with_self_signed_cert");
        HttpResponse response = httpclient.execute( httpGet );
        assertEquals("HTTP/1.1 200 OK", response.getStatusLine().toString());
    }

    private DefaultHttpClient httpClientTrustingAllSSLCerts() throws NoSuchAlgorithmException, KeyManagementException {
        DefaultHttpClient httpclient = new DefaultHttpClient();

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, getTrustingManager(), new java.security.SecureRandom());

        SSLSocketFactory socketFactory = new SSLSocketFactory(sc);
        Scheme sch = new Scheme("https", 443, socketFactory);
        httpclient.getConnectionManager().getSchemeRegistry().register(sch);
        return httpclient;
    }

    private TrustManager[] getTrustingManager() {
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            @Override
            public void checkClientTrusted(X509Certificate[] certs, String authType) {
                // Do nothing
            }

            @Override
            public void checkServerTrusted(X509Certificate[] certs, String authType) {
                // Do nothing
            }

        } };
        return trustAllCerts;
    }
}
方法返回“secureClient”(在Java 7环境中-NetBeans IDE和GlassFish服务器:端口https默认为3920),希望这能有所帮助:

public DefaultHttpClient secureClient() {
    DefaultHttpClient httpclient = new DefaultHttpClient();
    SSLSocketFactory sf;

    KeyStore trustStore;
    FileInputStream trustStream = null;
    File truststoreFile;
    // java.security.cert.PKIXParameters for the trustStore
    PKIXParameters pkixParamsTrust;

    KeyStore keyStore;
    FileInputStream keyStream = null;
    File keystoreFile;
    // java.security.cert.PKIXParameters for the keyStore
    PKIXParameters pkixParamsKey;

    try {
        trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
        truststoreFile = new File(TRUSTSTORE_FILE);
        keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keystoreFile = new File(KEYSTORE_FILE);
        try {
            trustStream = new FileInputStream(truststoreFile);
            keyStream = new FileInputStream(keystoreFile);
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            trustStore.load(trustStream, PASSWORD.toCharArray());
            keyStore.load(keyStream, PASSWORD.toCharArray());
        } catch (IOException ex) {
            Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (CertificateException ex) {
            Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            pkixParamsTrust = new PKIXParameters(trustStore);
            // accepts Server certificate generated with keytool and (auto) signed by SUN
            pkixParamsTrust.setPolicyQualifiersRejected(false);
        } catch (InvalidAlgorithmParameterException ex) {
            Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            pkixParamsKey = new PKIXParameters(keyStore);
            // accepts Client certificate generated with keytool and (auto) signed by SUN
            pkixParamsKey.setPolicyQualifiersRejected(false);
        } catch (InvalidAlgorithmParameterException ex) {
            Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            sf = new SSLSocketFactory(trustStore);
            ClientConnectionManager manager = httpclient.getConnectionManager();
            manager.getSchemeRegistry().register(new Scheme("https", 3920, sf));
        } catch (KeyManagementException ex) {
            Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnrecoverableKeyException ex) {
            Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
        }

    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
    } catch (KeyStoreException ex) {
        Logger.getLogger(ApacheHttpRestClient.class.getName()).log(Level.SEVERE, null, ex);
    }
    // use the httpclient for any httpRequest
    return httpclient;
}
这个答案是根据和的回答得出的。它适用于SE/EE安装,而不是ME/mobile/Android SSL

由于还没有人提到这一点,我将提到解决这一问题的“生产方式”: 按照中的步骤更新您的信任存储和密钥存储

  • 导入受信任证书并生成信任库文件
  • keytool-import-别名“我的服务器证书”-file server.crt-keystore my.truststore

  • 生成新密钥(使用与信任库相同的密码)
  • keytool-genkey-v-别名“我的客户端密钥”-有效期365-密钥库我的密钥库

  • 发出证书签名请求(CSR)
  • keytool-certreq-别名“我的客户端密钥”-文件mycertreq.csr-keystore my.keystore

  • (自行签名或让您的证书签名)

  • 导入受信任的CA根证书

  • keytool-import-alias“my trusted ca”-文件caroot.crt-keystore my.keystore

  • 导入包含完整证书链的PKCS#7文件
  • keytool-import-别名“我的客户端密钥”-文件mycert.p7-密钥库my.keystore

  • 验证生成的密钥库文件的内容
  • keytool-list-v-keystoremy.keystore

    如果您没有服务器证书,请生成一个JKS格式的证书,然后将其导出为CRT文件


    如果您的服务器基于JDK 7,而您的客户端位于JDK 6上并使用SSL证书,则会出现此异常。在JDK 7中,默认情况下禁用sslv2hello消息握手,而在JDK 6中启用sslv2hello消息握手。因此,当您的客户端尝试连接服务器时,将向服务器发送sslv2hello消息,并且由于sslv2hello消息禁用,您将获得此异常。要解决这个问题,您必须将客户端移动到JDK 7,或者必须使用JDK的6u91版本。但是要获得这个版本的JDK,您必须获得本地JVM或远程服务器可能没有所需的密码。到这里来

    并下载包含以下内容的zip文件: 美国出口政策.jar 及 local_policy.jar

    替换现有文件(您需要在JVM中找到现有路径)

    在Mac电脑上,我的路径就在这里。 /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/security


    这对我很有用。

    JDK版本?HttpClient版本?此外,如果您可以提供完整的堆栈跟踪和URL(它是否是公共网站,您是否使用自签名证书),它可能会有所帮助。它是自签名证书。我链接到我使用的HttpClient版本(4.x,任何稳定的版本),我使用的是Java 6。无论连接到哪个站点,我都需要忽略此错误并执行get。读者可能对此相关问题感兴趣:请注意,最好创建一个特定的
    密钥库
    信任管理器
    ,以连接到未经预安装的根证书之一验证的特定服务器,或者创建并使用自签名证书。如果您只是跳过了这个问题,那么您的SSL连接就不再安全了。更新了URL。你真正需要做的就是谷歌
    EasySSLProtocolSocketFactory
    。确切的字符串非常具体,似乎没有坏的结果。应该注意的是,此方法完全符合问题的要求:它抑制错误消息。因为连接不安全,所以它实际上并不能解决问题。正确的方法是在您的信任存储中明确导入远程证书。这并不能解决问题,链接会指向一个已停止的页面:。而且,对于任何对安全感兴趣的人来说,这也不能解决根本问题。在您的证书存储中导入证书,但不要信任所有连接,因为您最好不要使用SSL。当然。在生产代码中执行上述操作会产生难以置信的反效果。但是,如果您不关心安全性,例如在针对开发服务器的端到端测试中,不依赖服务器证书是很好的。感谢您的编辑,明确显示此类安全警告不会有什么坏处。@owlstead“您最好不要使用SSL”我使用SSL只是为了加密,而不是为了向客户端验证服务器,这怎么不安全?我想你使用加密的目的是防止中间人读取你的数据。如果是这样的话,在不验证证书的情况下,您不知道谁在另一端,可能是中间的人代理通信,即解密、读取、加密、传递。您永远不会知道……值得注意的是,只有在您也需要实现客户端身份验证时(即,让服务器对客户端进行身份验证),才需要执行步骤2-7。在大多数情况下,仅步骤1就足够了。如何创建server.crt?编辑以包括server.crt创建步骤。
    keytool -genkey -alias server-alias -keyalg RSA -keypass changeit
        -storepass changeit -keystore my.keystore
    
    keytool -export -alias server-alias -storepass changeit
        -file server.crt -keystore my.keystore