System.err:javax.net.ssl.SSLPeerUnverifiedException:没有对等证书

时间:2016-03-22 10:02:48

标签: java android security ssl https

1)我正在尝试从Android手机发出HTTPS请求 所以我使用下面的命令

创建了filename.bks文件

我已将我从Godaddy收到的ssl证书“load-der.crt”重命名为“cert.pem”。然后我在下面的命令

中使用了这个文件
keytool -import -alias tomcat -file C:/Users/Masthan/Desktop/BKS/cert.pem -keypass password -keystore C:/Users/Masthan/Desktop/BKS/keystore.bks -storetype BKS -storepass 222222 -providerClass org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath C:/Users/Masthan/Desktop/BKS/bcprov-ext-jdk15on-1.46.jar

2)然后我在下面的代码中使用了这个bks文件

public class MyHttpClient extends DefaultHttpClient {
final Context context;

public MyHttpClient(Context context) {
    this.context = context;
}

@Override
protected ClientConnectionManager createClientConnectionManager() {
    SchemeRegistry registry = new SchemeRegistry();

    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));

    // Register for port 443 our SSLSocketFactory with our keystore to the ConnectionManager
    registry.register(new Scheme("https", newSslSocketFactory(), 443));
    return new SingleClientConnManager(getParams(), registry);
}

private SSLSocketFactory newSslSocketFactory() {
    try {
        // Get an instance of the Bouncy Castle KeyStore format
        KeyStore trusted = KeyStore.getInstance("BKS");

        // Get the raw resource, which contains the keystore with your trusted certificates (root and any intermediate certs)
        InputStream in = context.getResources().openRawResource(R.raw.keystore);
        try {
            // Initialize the keystore with the provided trusted certificates.
            // Also provide the password of the keystore
            trusted.load(in, "222222".toCharArray());
        } finally {
            in.close();
        }

        // Pass the keystore to the SSLSocketFactory. The factory is responsible for the verification of the server certificate.
        SSLSocketFactory sf = new SSLSocketFactory(trusted);

        // Hostname verification from certificate
        // http://hc.apache.org/httpcomponents-client-ga/tutorial/html/connmgmt.html#d4e506
        sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
        return sf;
    } catch (Exception e) {
        throw new AssertionError(e);
    }
}}

然后我使用上面的MyHttpsClient类向服务器请求如下

HttpClient httpClient = new MyHttpClient(getApplicationContext());
HttpPost httpPost = new HttpPost("https://xxxxx.co.in/");
HttpResponse httpResponse = httpClient.execute(httpPost);

3)执行语句“HttpResponse httpResponse = httpClient.execute(httpPost);”

我收到了这个错误:

03-22 15:13:56.178  30079-30173/com.revu.revu W/System.err﹕ javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
    03-22 15:13:56.230  30079-30173/com.revu.revu W/System.err﹕ at com.android.org.conscrypt.SSLNullSession.getPeerCertificates(SSLNullSession.java:104)
    03-22 15:13:56.263  30079-30173/com.revu.revu W/System.err﹕ at org.apache.http.conn.ssl.AbstractVerifier.verify(AbstractVerifier.java:98)
    03-22 15:13:56.312  30079-30173/com.revu.revu W/System.err﹕ at org.apache.http.conn.ssl.SSLSocketFactory.createSocket(SSLSocketFactory.java:393)
    03-22 15:13:56.353  30079-30173/com.revu.revu W/System.err﹕ at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:170)
    03-22 15:13:56.388  30079-30173/com.revu.revu W/System.err﹕ at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:169)
    03-22 15:13:56.426  30079-30173/com.revu.revu W/System.err﹕ at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:124)
    03-22 15:13:56.469  30079-30173/com.revu.revu W/System.err﹕ at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:379)
    03-22 15:13:56.508  30079-30173/com.revu.revu W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:580)
    03-22 15:13:56.545  30079-30173/com.revu.revu W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:503)
    03-22 15:13:56.583  30079-30173/com.revu.revu W/System.err﹕ at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:481)

1 个答案:

答案 0 :(得分:0)

// Load CAs from an InputStream
                    // (could be from a resource or ByteArrayInputStream or ...)
                    CertificateFactory cf = CertificateFactory.getInstance("X.509");
                    // From https://www.washington.edu/itconnect/security/ca/load-der.crt
                    AssetManager am = getAssets();
                    InputStream caInput = new BufferedInputStream(am.open("your_cert.crt"));
                    Certificate ca;
                    try {
                        ca = cf.generateCertificate(caInput);
                        System.out.println("ca=" + ((X509Certificate) ca).getSubjectDN());
                    } finally {
                        caInput.close();
                    }
                // Create a KeyStore containing our trusted CAs
                String keyStoreType = KeyStore.getDefaultType();
                KeyStore keyStore = KeyStore.getInstance(keyStoreType);
                keyStore.load(null, null);
                keyStore.setCertificateEntry("ca", ca);

               TrustManager[] trustManagers = tmf.getTrustManagers();
final X509TrustManager origTrustmanager = (X509TrustManager)trustManagers[0];

TrustManager[] wrappedTrustManagers = new TrustManager[]{
   new X509TrustManager() {
       public java.security.cert.X509Certificate[] getAcceptedIssuers() {
          return origTrustmanager.getAcceptedIssuers();
       }

       public void checkClientTrusted(X509Certificate[] certs, String authType) {
           origTrustmanager.checkClientTrusted(certs, authType);
       }

       public void checkServerTrusted(X509Certificate[] certs, String authType) {
           try {
               origTrustmanager.checkServerTrusted(certs, authType);
           } catch (CertificateExpiredException e) {}
       }
   }
};

SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, wrappedTrustManagers, null);
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); 




                // Tell the URLConnection to use a SocketFactory from our SSLContext
                AppLog.LogE(getClass().getName(), "Licensing Url is " + request.toString());
                URL url = new URL(request.toString());
                HttpsURLConnection urlConnection =
                        (HttpsURLConnection)url.openConnection();
                urlConnection.setSSLSocketFactory(context.getSocketFactory());
                InputStream in = urlConnection.getInputStream();
                String line = "";
                BufferedReader rd = new BufferedReader(new InputStreamReader(in));
                while ((line = rd.readLine()) != null) {
                    strResponse += line;
                }

希望这有助于您实现目标。