|
android SSL证书校验方法与教程
(福利推荐:阿里云企业SSL证书限时优惠,还有免费SSL证书申请:点击这里立即进入了解;腾讯云企业SSL证书优惠活动也在进行中:点击这里立即参加,同样有免费企业SSL证书申请哦!)
1. 背景与需求
近期在做IP切换的HTTPS访问时,遇到了一些问题:客户端如何进行HTTPS的证书验证。
其实对于一般的项目基本都是做的单向验证,即在客户端证书或者HOST的验证;对于金融、银行相关的项目才会使用的双向验证,客户端与服务端之间都要对彼此进行验证,以防止中间人进行攻击。
2.实现目标
本文记录的是:客户端实现对HOST的验证,这样基本满足一般项目的需求,也不需要客户端内置证书,引起更新时候的麻烦。
3. 实现过程
实现SSLSocketFactory ,获取SSLContext
我们这里没有本地的证书,所以都是生成TrustManager 时都是空实现,如果需要通过内置证书来验证可以柴查看下面的链接。
- public class SSLSocketFactoryImp extends SSLSocketFactory {
- private SSLContext sslContext = SSLContext.getInstance("TLS");
- private TrustManager trustManager = null;
- public SSLContext getSSLContext() {
- return sslContext;
- }
- public X509TrustManager getTrustManager() {
- return (X509TrustManager)trustManager;
- }
- public SSLSocketFactoryImp(KeyStore keyStore) throws NoSuchAlgorithmException, KeyManagementException {
- trustManager = new X509TrustManager() {
- @Override
- public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
- }
- @Override
- public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
- }
- @Override
- public X509Certificate[] getAcceptedIssuers() {
- X509Certificate[] x509Certificates = new X509Certificate[0];
- return x509Certificates;
- }
- };
- sslContext.init(null, new TrustManager[]{trustManager}, null);
- }
- @Override
- public String[] getDefaultCipherSuites() {
- return new String[0];
- }
- @Override
- public String[] getSupportedCipherSuites() {
- return new String[0];
- }
- @Override
- public Socket createSocket() throws IOException {
- return sslContext.getSocketFactory().createSocket();
- }
- @Override
- public Socket createSocket(Socket socket, String host, int post, boolean autoClose) throws IOException {
- return sslContext.getSocketFactory().createSocket(socket, host, post, autoClose);
- }
- @Override
- public Socket createSocket(String s, int i) throws IOException, UnknownHostException {
- return null;
- }
- @Override
- public Socket createSocket(String s, int i, InetAddress inetAddress, int i1) throws IOException, UnknownHostException {
- return null;
- }
- @Override
- public Socket createSocket(InetAddress inetAddress, int i) throws IOException {
- return null;
- }
- @Override
- public Socket createSocket(InetAddress inetAddress, int i, InetAddress inetAddress1, int i1) throws IOException {
- return null;
- }
- }
复制代码 关键步骤:验证HOST
这里是基于OKHTTP来进行的验证操作,主要依靠:HttpsURLConnection.getDefaultHostnameVerifier().verify("你的域名", session)方法来验证域名是否一致
- KeyStore trustStore;
- trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
- trustStore.load(null, null);
- SSLSocketFactoryImp ssl = new SSLSocketFactoryImp(KeyStore.getInstance(KeyStore.getDefaultType()));
- HostnameVerifier hostnameVerifier = new HostnameVerifier() {
- @Override
- public boolean verify(String hostname, SSLSession session) {
- boolean verify = HttpsURLConnection.getDefaultHostnameVerifier().verify("你的域名", session);
- return verify;
- }
- };
- builder.sslSocketFactory(ssl.getSSLContext().getSocketFactory(), ssl.getTrustManager()).hostnameVerifier
- (hostnameVerifier);
复制代码
|
|