接受具有自签名证书的HTTPS连接

接受具有自签名证书的HTTPS连接

我试图建立HTTPS连接,使用HttpClient但是问题是,由于证书不是由一个公认的证书颁发机构(CA)签署的,维瑞,环球信等等,在android可信证书集上,我一直得到javax.net.ssl.SSLException: Not trusted server certificate.

我已经看到了简单地接受所有证书的解决方案,但是如果我想问用户呢?

我想要一个类似浏览器的对话框,让用户决定是否继续。最好我想使用与浏览器相同的证书。有什么想法吗?


慕森卡
浏览 398回答 3
3回答

红糖糍粑

如果服务器上的设备上没有自定义/自签名证书,则可以使用下面的类加载它,并在Android的客户端使用它:放置证书*.crt文件在/res/raw使其可从R.raw.*使用下面的类获取HTTPClient或HttpsURLConnection它将有一个套接字工厂使用该证书:package com.example.customssl;import android.content.Context;import org.apache.http.client.HttpClient;import org.apache.http.conn.scheme. PlainSocketFactory;import org.apache.http.conn.scheme.Scheme;import org.apache.http.conn.scheme.SchemeRegistry;import org.apache.http.conn .ssl.AllowAllHostnameVerifier;import org.apache.http.conn.ssl.SSLSocketFactory;import org.apache.http.impl.client.DefaultHttpClient;import  org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;import org.apache.http.params.BasicHttpParams;import org.apache.http.params.Ht tpParams;import javax.net.ssl.HttpsURLConnection;import javax.net.ssl.SSLContext;import javax.net.ssl.TrustManagerFactory;import java.io.IO Exception;import java.io.InputStream;import java.net.URL;import java.security.KeyStore;import java.security.KeyStoreException;import java.s ecurity.NoSuchAlgorithmException;import java.security.cert.Certificate;import java.security.cert.CertificateException;import java.security. cert.CertificateFactory;public class CustomCAHttpsProvider {     /**      * Creates a {@link org.apache.http.client.HttpClient} which is configured to work with a custom authority      * certificate.      *      * @param context       Application Context      * @param certRawResId  R.raw.id of certificate file (*.crt). Should be stored in /res/raw.      * @param allowAllHosts If true then client will not check server against host names of certificate.      * @return Http Client.      * @throws Exception If there is an error initializing the client.      */     public static HttpClient getHttpClient(Context context, int certRawResId, boolean allowAllHosts) throws Exception {         // build key store with ca certificate         KeyStore keyStore = buildKeyStore(context, certRawResId);         // init ssl socket factory with key store         SSLSocketFactory sslSocketFactory = new SSLSocketFactory(keyStore);         // skip hostname security check if specified         if (allowAllHosts) {             sslSocketFactory.setHostnameVerifier(new AllowAllHostnameVerifier());         }         // basic http params for client         HttpParams params = new BasicHttpParams();         // normal scheme registry with our ssl socket factory for "https"         SchemeRegistry schemeRegistry = new SchemeRegistry();         schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));         schemeRegistry.register(new Scheme("https", sslSocketFactory, 443));         // create connection manager         ThreadSafeClientConnManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);         // create http client         return new DefaultHttpClient(cm, params);     }     /**      * Creates a {@link javax.net.ssl.HttpsURLConnection} which is configured to work with a custom authority      * certificate.      *      * @param urlString     remote url string.      * @param context       Application Context      * @param certRawResId  R.raw.id of certificate file (*.crt). Should be stored in /res/raw.      * @param allowAllHosts If true then client will not check server against host names of certificate.      * @return Http url connection.      * @throws Exception If there is an error initializing the connection.      */     public static HttpsURLConnection getHttpsUrlConnection(String urlString, Context context, int certRawResId,                                                            boolean allowAllHosts) throws Exception {         // build key store with ca certificate         KeyStore keyStore = buildKeyStore(context, certRawResId);         // Create a TrustManager that trusts the CAs in our KeyStore         String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();         TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);         tmf.init(keyStore);         // Create an SSLContext that uses our TrustManager         SSLContext sslContext = SSLContext.getInstance("TLS");         sslContext.init(null, tmf.getTrustManagers(), null);         // Create a connection from url         URL url = new URL(urlString);         HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();         urlConnection.setSSLSocketFactory(sslContext.getSocketFactory());         // skip hostname security check if specified         if (allowAllHosts) {             urlConnection.setHostnameVerifier(new AllowAllHostnameVerifier());         }         return urlConnection;     }     private static KeyStore buildKeyStore(Context context, int certRawResId) throws KeyStoreException, CertificateException,      NoSuchAlgorithmException, IOException {         // init a default key store         String keyStoreType = KeyStore.getDefaultType();         KeyStore keyStore = KeyStore.getInstance(keyStoreType);         keyStore.load(null, null);         // read and add certificate authority         Certificate cert = readCert(context, certRawResId);         keyStore.setCertificateEntry("ca", cert);         return keyStore;     }     private static Certificate readCert(Context context, int certResourceId) throws CertificateException, IOException {         // read certificate resource         InputStream caInput = context.getResources().openRawResource(certResourceId);         Certificate ca;         try {             // generate a certificate             CertificateFactory cf = CertificateFactory.getInstance("X.509");             ca = cf.generateCertificate(caInput);         } finally {             caInput.close();         }         return ca;     }}要点:Certificate对象是从.crt档案。违约KeyStore是被创造出来的。keyStore.setCertificateEntry("ca", cert)将证书添加到别名“ca”下的密钥存储区。您可以修改代码以添加更多证书(中间CA等)。主要目标是生成一个SSLSocketFactory然后可以由HTTPClient或HttpsURLConnection.SSLSocketFactory可以进一步配置,例如跳过主机名验证等。详情见:http:/developer.android.com/培训/文章/安全-ssl.html
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Android