https HttpsURLConnection请求的单向认证

参考链接

android httpClient(https/http)的优化构建方式一

android httpClient(https/http)的优化构建方式二

Java https请求 HttpsURLConnection

php使用curl库进行ssl双向认证

OpenSSL生成根证书CA及签发子证书

Java使用SSLSocket通信

android 让webview支持https 双向认证(SSL)(一)

android 让webview支持https 双向认证(SSL)(二)

webview的自定义SSL认证配置(p12证书)

 

Https访问的相关知识中,主要分为单项验证和双向验证,双向验证在单项验证的基础上构建而成

 

关于单项验证,如果要细分的话,分为证书验证和普通验证(忽略验证),因为这项验证针对客户端,所以客户端有能力控制是否需要验证

 

忽略验证的方式

主要如下继承X509TrustManager和HostnameVerifier

public class SSLTrustManager implements javax.net.ssl.TrustManager,
            javax.net.ssl.X509TrustManager ,HostnameVerifier{
        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
            return null;
        }
  
        public boolean isServerTrusted(
                java.security.cert.X509Certificate[] certs) {
            return true;
        }
  
        public boolean isClientTrusted(
                java.security.cert.X509Certificate[] certs) {
            return true;
        }
  
        public void checkServerTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }
  
        public void checkClientTrusted(
                java.security.cert.X509Certificate[] certs, String authType)
                throws java.security.cert.CertificateException {
            return;
        }
         
            @Override
        public boolean verify(String urlHostName, SSLSession session) { //允许所有主机
            return true;
        }
        
   //封装
public static HttpURLConnection connect(String strUrl) throws Exception {
         
         javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
         javax.net.ssl.TrustManager tm = new SSLTrustManager();
         trustAllCerts[0] = tm;
         javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext
                 .getInstance("SSL");
         sc.init(null, trustAllCerts, null);
         javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc
                 .getSocketFactory());
          
         HttpsURLConnection.setDefaultHostnameVerifier((HostnameVerifier) tm);
          
        URL url = new URL(strUrl);
        HttpURLConnection urlConn = (HttpURLConnection) url.openConnection();
      
        return urlConn;
    }
        
 }
双向证书验证方式

如下,这里采用双向验证

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.GeneralSecurityException;
import java.security.KeyStore;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;

public class HttpsPost {
    /**
     * 获得KeyStore.
     * @param keyStorePath
     *            密钥库路径
     * @param password
     *            密码
     * @return 密钥库
     * @throws Exception
     */
    public static KeyStore getKeyStore(String password, String keyStorePath)
            throws Exception {
        // 实例化密钥库
        KeyStore ks = KeyStore.getInstance("JKS");
        // 获得密钥库文件流
        FileInputStream is = new FileInputStream(keyStorePath);
        // 加载密钥库
        ks.load(is, password.toCharArray());
        // 关闭密钥库文件流
        is.close();
        return ks;
    }

    /**
     * 获得SSLSocketFactory.
     * @param password
     *            密码
     * @param keyStorePath
     *            密钥库路径
     * @param trustStorePath
     *            信任库路径
     * @return SSLSocketFactory
     * @throws Exception
     */
    public static SSLContext getSSLContext(String password,
            String keyStorePath, String trustStorePath) throws Exception {
        // 实例化密钥库
        KeyManagerFactory keyManagerFactory = KeyManagerFactory
                .getInstance(KeyManagerFactory.getDefaultAlgorithm());
        // 获得密钥库
        KeyStore keyStore = getKeyStore(password, keyStorePath);
        // 初始化密钥工厂
        keyManagerFactory.init(keyStore, password.toCharArray());

        // 实例化信任库
        TrustManagerFactory trustManagerFactory = TrustManagerFactory
                .getInstance(TrustManagerFactory.getDefaultAlgorithm());
        // 获得信任库
        KeyStore trustStore = getKeyStore(password, trustStorePath);
        // 初始化信任库
        trustManagerFactory.init(trustStore);
        // 实例化SSL上下文
        SSLContext ctx = SSLContext.getInstance("TLS");
        // 初始化SSL上下文
        ctx.init(keyManagerFactory.getKeyManagers(),
                trustManagerFactory.getTrustManagers(), null);
        // 获得SSLSocketFactory
        return ctx;
    }

    /**
     * 初始化HttpsURLConnection.
     * @param password
     *            密码
     * @param keyStorePath
     *            密钥库路径
     * @param trustStorePath
     *            信任库路径
     * @throws Exception
     */
    public static void initHttpsURLConnection(String password,
            String keyStorePath, String trustStorePath) throws Exception {
        // 声明SSL上下文
        SSLContext sslContext = null;
        // 实例化主机名验证接口
        HostnameVerifier hnv = new MyHostnameVerifier();
        try {
            sslContext = getSSLContext(password, keyStorePath, trustStorePath);
        } catch (GeneralSecurityException e) {
            e.printStackTrace();
        }
        if (sslContext != null) {
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext
                    .getSocketFactory());
        }
        HttpsURLConnection.setDefaultHostnameVerifier(hnv);
    }

    /**
     * 发送请求.
     * @param httpsUrl
     *            请求的地址
     * @param xmlStr
     *            请求的数据
     */
    public static void post(String httpsUrl, String xmlStr) {
        HttpsURLConnection urlCon = null;
        try {
            urlCon = (HttpsURLConnection) (new URL(httpsUrl)).openConnection();
            urlCon.setDoInput(true);
            urlCon.setDoOutput(true);
            urlCon.setRequestMethod("POST");
            urlCon.setRequestProperty("Content-Length",
                    String.valueOf(xmlStr.getBytes().length));
            urlCon.setUseCaches(false);
            //设置为gbk可以解决服务器接收时读取的数据中文乱码问题
            urlCon.getOutputStream().write(xmlStr.getBytes("gbk"));
            urlCon.getOutputStream().flush();
            urlCon.getOutputStream().close();
            BufferedReader in = new BufferedReader(new InputStreamReader(
                    urlCon.getInputStream()));
            String line;
            while ((line = in.readLine()) != null) {
                System.out.println(line);
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 测试方法.
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        // 密码
        String password = "123456";
        // 密钥库
        String keyStorePath = "tomcat.keystore";
        // 信任库
        String trustStorePath = "tomcat.keystore";
        // 本地起的https服务
        String httpsUrl = "https://localhost:8443/service/httpsPost";
        // 传输文本
        String xmlStr = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><fruitShop><fruits><fruit><kind>萝卜</kind></fruit><fruit><kind>菠萝</kind></fruit></fruits></fruitShop>";
        HttpsPost.initHttpsURLConnection(password, keyStorePath, trustStorePath);
        // 发起请求
        HttpsPost.post(httpsUrl, xmlStr);
    }
}
单向证书验证
public static KeyStore getHttpsKeyStore()
	{
	    InputStream ins = null;
	    try {
	    	
	    	    ins = new FileInputStream("srca.cer"); 
	            //读取证书
	            CertificateFactory cerFactory = CertificateFactory.getInstance("X.509");  //问1
	            Certificate cer = cerFactory.generateCertificate(ins);
	            //创建一个证书库,并将证书导入证书库
	            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());   //问2
	            keyStore.load(null, null);
	            keyStore.setCertificateEntry("trust", cer);
	            return keyStore;
	    } catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(ins!=null)
			{
	            try {
					ins.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
	    }
	    return null;
	}
public void initSSLContext()
{
        SSLContext sslContext = SSLContext.getInstance("TLS");
        TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); 
        trustManagerFactory.init(getHttpsKeyStore());
        sslContext.init( null, trustManagerFactory.getTrustManagers(), new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
                    
        HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() {
       
        @Override
        public boolean verify(String hostname, SSLSession sslsession) {
      
        if("localhost".equals(hostname)){  
            return true;  
        } else {  
            return false;  
        }  
      }
  });
}

转载于:https://my.oschina.net/ososchina/blog/500925

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值