[英]Android How to allow specific SSL certificate from a specific server
I'm trying to connect to my secured server using HTTPS using DefaultHttpClient. 我正在尝试使用DefaultHttpClient使用HTTPS连接到我的安全服务器。
My server is using PositiveSSL certificate and every check i've made through the SSL checkers online - gives an A grade for the certificate. 我的服务器使用的是PositiveSSL证书,我通过SSL检查器在线进行的每项检查都为该证书提供A级。
Apperantly, PositiveSSL is not a verified CA Root in Android so when i'm ever i'm trying to connect to my server I'm receiving the javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
which is discussed here in various questions. 显然,PositiveSSL不是Android中经过验证的CA Root,因此,当我尝试连接到服务器时,会收到
javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
在这里讨论各种问题的javax.net.ssl.SSLPeerUnverifiedException: No peer certificate
。
One of the given solution (that was the best for me) is to create a custom SSLFactory and to allow it to accept the unverified certificate, in case this certificate is coming from my server (to set the allowed server's name). 给定的解决方案之一(最适合我的方法)是创建一个自定义SSLFactory,并允许它接受未验证的证书,以防该证书来自我的服务器(设置允许的服务器名称)。
I couldn't find any code examples on how to do it.. would be great if someone will be kind to help me with that 我找不到任何有关如何执行此操作的代码示例。如果有人愿意帮助我,那将非常好
Yopu can Write you Custom SSLSocketFactory as given below Yopu可以按如下所示为您编写自定义SSLSocketFactory
public class MySSLSocketFactory extends SSLSocketFactory {
SSLContext sslContext = SSLContext.getInstance("TLS");
public MySSLSocketFactory(KeyStore truststore)
throws NoSuchAlgorithmException, KeyManagementException,
KeyStoreException, UnrecoverableKeyException {
super(truststore);
TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
sslContext.init(null, new TrustManager[]{tm}, null);
}
@Override
public Socket createSocket(Socket socket, String host, int port,
boolean autoClose) throws IOException, UnknownHostException {
return sslContext.getSocketFactory().createSocket(socket, host, port,
autoClose);
}
@Override
public Socket createSocket() throws IOException {
return sslContext.getSocketFactory().createSocket();
}
}
Now Create a Custom HttpClient using the SocketFactory to by Pass the certificate. 现在,使用SocketFactory创建自定义HttpClient,以通过证书。 You can also accept some particular Certificate as well using your SockeFactory.
您也可以使用SockeFactory接受某些特定的证书。
public static DefaultHttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (UnrecoverableKeyException e) {
return new DefaultHttpClient();
} catch (NoSuchAlgorithmException e) {
return new DefaultHttpClient();
} catch (CertificateException e) {
return new DefaultHttpClient();
} catch (IOException e) {
return new DefaultHttpClient();
} catch (KeyStoreException e) {
return new DefaultHttpClient();
} catch (KeyManagementException e) {
return new DefaultHttpClient();
}
}
Now Use instantiate httpclient as mentioned : 现在使用提到的实例化httpclient:
DefaultHttpClient client = getNewHttpClient();
Check emmby Answer on this post 检查此帖子的emmby答案
Trusting all certificates using HttpClient over HTTPS 通过HTTPS使用HttpClient信任所有证书
UPDATED : 更新 :
If you want to verify only some particular server. 如果您只想验证某些特定服务器。 Open the url in browser with Https and download the certificate from the url bar , Its easy Google it how to do that.
在浏览器中使用Https打开url,然后从url栏中下载证书,这很简单,Google如何操作。 It will give you a certificate file.
它会给您一个证书文件。
Copy that certificate in your assest folder. 将该证书复制到您的资产文件夹中。 and do the following.
并执行以下操作。
private X509Certificate getCertFromFile(String path) throws Exception {
AssetManager assetManager = MyActivity.this.getResources().getAssets();
InputStream inputStream = null;
try {
inputStream = assetManager.open(path);
} catch (IOException e) {
e.printStackTrace();
}
InputStream caInput = new BufferedInputStream(inputStream);
X509Certificate cert = null;
CertificateFactory cf = CertificateFactory.getInstance("X509");
cert = (X509Certificate) cf.generateCertificate(caInput);
cert.getSerialNumber();
return cert;
}
Now in above code for socket Factory return this certificate instead of null. 现在,在上面用于套接字工厂的代码中,返回此证书而不是null。
@Override
public X509Certificate[] getAcceptedIssuers() {
X509Certificate[] certificates=new X509Certificate[]{getCertFromFile(PATH_OF_CERTIFICATE_FILE)};
return certificates;
//asset folder path is taken in method.Only provide path respective to asset folder like /certificate/MyCertificate.crt inside assest.
}
You can place the custom server certificate in a custom trust store (BKS file), include it in your app and initialize your SSLSocketFactory with it: 您可以将自定义服务器证书放在自定义信任存储区(BKS文件)中,将其包含在应用程序中,并使用它初始化SSLSocketFactory:
SSLSocketFactory sslSocketFactory = new SSLSocketFactory(trustStore);
Afterwards use that SSLSocketFactory for creating your connections. 然后,使用该SSLSocketFactory创建连接。
In such a case only connections to servers which certificate is included in the key store. 在这种情况下,仅连接到密钥库中包含证书的服务器。
A very good example how this can be used with HttpClient can be found on Nikolay Elenkov's home page (section Using your own trust store: HttpClient ): 可以在Nikolay Elenkov的主页上找到一个很好的示例,该示例可以与HttpClient一起使用( 使用您自己的信任存储区:HttpClient一节 ):
http://nelenkov.blogspot.de/2011/12/using-custom-certificate-trust-store-on.html http://nelenkov.blogspot.de/2011/12/using-custom-certificate-trust-store-on.html
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.