首页 文章

修复javax.net.ssl.SSLPeerUnverifiedException:没有对等证书

提问于
浏览
1

我正在开发一个Android应用程序,必须通过https与服务器通信与自签名证书(SSL / TLS1.2) . 我也在使用Volley .

我正在关注this教程 . 保存了.crt文件,使用 keytool -importcert -v -trustcacerts -file "cert.crt" -alias IntermediateCA -keystore "key.bks" -provider org.bouncycastle.jce.provider.BouncyCastleProvider -providerpath "bcprov-jdk16-146.jar" -storetype BKS -storepass blabla 在原始目录中创建了key.bks,依此类推 .

当我向服务器发送数据时,Response.ErrorListener()收到无对等证书错误 .

试图发送我的json邮递员(当然,不得不添加证书) - 工作得很好 .

在我的Android设备上手动安装证书 - 工作正常

我怎样才能使它工作?

1 回答

  • 1

    我为这个问题奋斗了很多 . 我发送的服务器似乎有一个虚拟主机(托管在GAE上) . 在Android 5.0上,这个问题已经解决,但是对于Android 5.0,您必须自己添加SNI支持 . 以下是对此问题的解释http://blog.dev001.net/post/67082904181/android-using-sni-and-tlsv1-2-with-apache .

    因此,要使我的代码工作,我必须从教程中更改SslSocketFactory类 . 它做了魔术 .

    import java.io.IOException;
    import java.io.InputStream;
    import java.net.InetAddress;
    import java.net.Socket;
    import java.net.UnknownHostException;
    import java.security.GeneralSecurityException;
    import java.security.KeyManagementException;
    
    import java.security.KeyStoreException;
    import java.security.NoSuchAlgorithmException;
    import java.security.UnrecoverableKeyException;
    
    
    import javax.net.ssl.SSLSocket;
    import javax.net.ssl.TrustManager;
    
    import org.apache.http.conn.ssl.SSLSocketFactory;
    import org.apache.http.params.HttpParams;
    
    import android.annotation.TargetApi;
    import android.net.SSLCertificateSocketFactory;
    import android.os.Build;
    
    
     class SslSocketFactory extends SSLSocketFactory {
    
         InputStream mkeyStore;
         String mkeyStorePassword;
    
         public SslSocketFactory(InputStream keyStore, String keyStorePassword) throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException, KeyStoreException{
             super(null);
             mkeyStore=keyStore;
             mkeyStorePassword=keyStorePassword;
    
         }
    
    
    
          @Override
          public Socket connectSocket(Socket s, String host, int port, InetAddress localAddress, int localPort, HttpParams params) throws IOException {
              return null;
          }
    
          @Override
          public Socket createSocket() throws IOException {
              return null;
          }
    
          @Override
          public boolean isSecure(Socket s) throws IllegalArgumentException {
              if (s instanceof SSLSocket) {
                  return ((SSLSocket) s).isConnected();
              }
              return false;
          }
    
          @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
          @Override
          public Socket createSocket(Socket socket, String host, int port, boolean autoClose) throws IOException, UnknownHostException {
              SSLSocket sslSocket = null;
    
    
                  if (autoClose) {
                      socket.close();
                  }
    
    
                     SSLCertificateSocketFactory sslSocketFactory = (SSLCertificateSocketFactory) SSLCertificateSocketFactory.getDefault(0, null);
    
    
                  try {
                    sslSocketFactory.setTrustManagers(new TrustManager[] { new SsX509TrustManager( mkeyStore, mkeyStorePassword) });
                } catch (GeneralSecurityException e1) {
    
                    e1.printStackTrace();
                }
    
    
    
                  sslSocket = (SSLSocket) sslSocketFactory.createSocket(InetAddress.getByName(host), port);
    
                  sslSocket.setEnabledProtocols(sslSocket.getSupportedProtocols());
    
                  if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
    
                      sslSocketFactory.setHostname(sslSocket, host);
                  } else {
    
                      try {
                          java.lang.reflect.Method setHostnameMethod = sslSocket.getClass().getMethod("setHostname", String.class);
                          setHostnameMethod.invoke(sslSocket, host);
                      } catch (Exception e) {
    
                      }
                  }
    
    
              return sslSocket;
          }
    
      }
    

相关问题