http系列 - SSL请求,需要JKS证书的情况,如何做连接

 有些响应https请求的接口,需要在客户端添加证书的情况,其目的是加密在网络之间传输的请求报文,保证信息安全;

 

证书的加密方式多种多样,本案例以JKS加密的证书为例:

1.获取证书私钥PrivateKey 

private static PrivateKey getPrivateKey(String priKeyFile, String storePassword) throws Exception {
        char[] storePwdArr;
        int i;
        BufferedInputStream bis = null;
        try {
            KeyStore ks = KeyStore.getInstance("JKS");
            //加载证书
            FileInputStream fis = new FileInputStream(priKeyFile);
            bis = new BufferedInputStream(fis);
            //证书中的加密key
            String storeAlias = "signKey";
            storePwdArr = new char[storePassword.length()];// store password
            for (i = 0; i < storePassword.length(); i++) {
                storePwdArr[i] = storePassword.charAt(i);
            }
            ks.load(bis, storePwdArr);
            PrivateKey priv = (PrivateKey) ks.getKey(storeAlias, storePwdArr);
            return priv;
        } catch (KeyStoreException e) {
            e.printStackTrace();
            throw new Exception("1");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            throw new Exception("2", e);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            throw new Exception("3", e);
        } catch (CertificateException e) {
            e.printStackTrace();
            throw new Exception("4", e);
        } catch (IOException e) {
            e.printStackTrace();
            throw new Exception("5", e);
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
            throw new Exception("6", e);
        } finally {
            if (bis != null) {
                try {
                    bis.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

SSL实现(HTTP请求):

1.请求构建:

import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.protocol.Protocol;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * HTTP请求
 * 
 */
public class HttpRequestUtil
{
	final static String PROTOCOL_NAME = "https";
	
	
	private static final Logger logger = LoggerFactory.getLogger(HttpRequestUtil.class);
	
	public static String sendJsonWithHttp(String surl, String json) throws Exception
	{
		URL url = new URL(surl);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection();
		conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
		conn.setRequestMethod("POST");// 提交模式
		conn.setRequestProperty("Content-Length", json.getBytes().length + "");
		conn.setConnectTimeout(100000);// 连接超时单位毫秒 //
		conn.setReadTimeout(200000);// 读取超时 单位毫秒
		conn.setDoOutput(true);// 是否输入参数
		conn.setDoInput(true);
		conn.setUseCaches(false);
		conn.connect();
		DataOutputStream out = new DataOutputStream(conn.getOutputStream());
		out.write(json.getBytes());
		out.flush();
		out.close();
		BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
		StringBuffer sb = new StringBuffer();
		String line;
		while ((line = reader.readLine()) != null)
		{
			sb.append(line);
		}
		reader.close();
		conn.disconnect();
		return sb.toString();
	}
	public static  String https(String surl, String json)
	{
		HttpClient client =getHttpClient();
		
		
		client.getParams().setContentCharset("UTF-8");
		PostMethod post = new PostMethod(surl);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		Protocol httpProtocol;
		try {
            //声明协议类型
            httpProtocol = new Protocol(PROTOCOL_NAME, new SSLProtocolSocketFactory(false), 443);
           
			Protocol.registerProtocol(PROTOCOL_NAME, httpProtocol);
            //声明报文格式
			post.setRequestHeader("Content-Type", "application/json;charset=utf-8");
			RequestEntity requestEntity = null;
			requestEntity = new ByteArrayRequestEntity(json.getBytes("utf-8"));
			post.setRequestEntity(requestEntity);
            //执行调用
			client.executeMethod(post);
			String off = "ON";
            
			
			InputStream in = null;
			in = post.getResponseBodyAsStream();
			byte[] buf = new byte[2048];
			do
			{
				int n = in.read(buf);;
				if (n > 0)
				{
					baos.write(buf, 0, n);
				}
				else if (n <= 0)
				{
					break;
				}
			} while (true);
		}catch (HttpException e) {  
			logger.info("http exception when send http.", e);  
		} catch (IOException e) {  
			logger.info("io exception when send http.", e);  
		}
		finally {
			post.releaseConnection(); 
			httpProtocol=null;
		}
		return baos.toString();
	}
	private static HttpClient httpClient=null;
	public static  HttpClient getHttpClient()
	{
		if(httpClient==null)
		{
			HttpConnectionManager httpConnectionManager = new MultiThreadedHttpConnectionManager();
	        HttpConnectionManagerParams params = httpConnectionManager.getParams();
	        params.setConnectionTimeout(1000*60); 
	        params.setSoTimeout(20000); 
            //避免异常的两行diamante
	        params.setDefaultMaxConnectionsPerHost(1000);
	        params.setMaxTotalConnections(2000);
	        httpClient = new HttpClient(httpConnectionManager);
		}
		
		return httpClient;
	}
}

2.SSLProtocolSocketFactory必不可少

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;

import javax.net.SocketFactory;

import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;

/**
 * 
 */
public class SSLProtocolSocketFactory implements ProtocolSocketFactory {
    private boolean isChkCert;

    public SSLProtocolSocketFactory(boolean chkCert) {
        this.isChkCert = chkCert;
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localAddress, int localPort, HttpConnectionParams params) throws IOException, UnknownHostException, ConnectTimeoutException {
        if (params == null) {
            throw new IllegalArgumentException("Parameters may not be null!");
        }
        int timeout = params.getConnectionTimeout();
        SocketFactory socketFactory = SSLContextFactory.getInstance(this.isChkCert).getSocketFactory();
        if (timeout == 0) {
            return createSocket(host, port, localAddress, localPort);
        }
        Socket socket = socketFactory.createSocket();
        SocketAddress localAddress_ = new InetSocketAddress(localAddress, localPort);
        SocketAddress remoteAddress = new InetSocketAddress(host, port);
        socket.bind(localAddress_);
        socket.connect(remoteAddress, timeout);
        return socket;
    }

    @Override
    public Socket createSocket(String host, int port, InetAddress localAddress, int localPort) throws IOException, UnknownHostException {
        return SSLContextFactory.getInstance(this.isChkCert).getSocketFactory().createSocket(host, port, localAddress, localPort);
    }

    @Override
    public Socket createSocket(String host, int port) throws IOException, UnknownHostException {
        return SSLContextFactory.getInstance(this.isChkCert).getSocketFactory().createSocket(host, port);
    }
}

3.SSLContextFactory 

import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 
 */
public class SSLContextFactory {
    private static final Logger logger = LoggerFactory.getLogger(SSLContextFactory.class);
    private static SSLContext ctx;
    private final static String PROTOCAL_NAME = "SSL";

    public static SSLContext getInstance(boolean chkCert) {
        if (ctx == null) {
            try {
                ctx = SSLContext.getInstance(PROTOCAL_NAME);
                if (chkCert) {
                    logger.error("请实现证书信任连接!");
                } else {
                    ctx.init(null, new TrustManager[] {new TrustAnyTrustManager()}, new SecureRandom());
                }
            } catch (NoSuchAlgorithmException e) {
                e.printStackTrace();
            } catch (KeyManagementException e) {
                e.printStackTrace();
            }
            return ctx;
        }
        return ctx;
    }
}

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值