https实现双向验证请求
2017-08-15 18:10
239 查看
前言:
1、 某一次调上游接口过程中,测试环境用http,但生产环境需要用https,故将http改造成https,记录在此,以便之后参考;
2、https比http更安全,http明文传输,https密文传输;
3、https三次服务器握手,先验证服务器的可信性,然后进行数据加密传输;
4、该实例继承httpclient实现https通讯;
5、TLS是SSL 3.0的升级版;
https相关文件说明:
1、xxx.keystore // 服务器证书库,配置在web服务端,tomcat的server.xml中;
2、xxxTrust.keystore // 客户端信任证书库,由服务端证书生产;
3、*.cer // 客户端证书,由客户端证书库导出;
4、*.cer // 服务端证书,由服务端证书库导出;
5、客户端证书库、服务器证书库都设置,表示双向验证,如果只传其中一个,表示单向数据传输验证;
6、https与http的代码不同之处,在于sslContext的获取;
相关jar包:
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
代码说明:
本实例只实现了https双向验证中的客户端验证,具体服务器端的验证和配置(主要是web服务器配置)这里不涉及
代码如下:
1、 某一次调上游接口过程中,测试环境用http,但生产环境需要用https,故将http改造成https,记录在此,以便之后参考;
2、https比http更安全,http明文传输,https密文传输;
3、https三次服务器握手,先验证服务器的可信性,然后进行数据加密传输;
4、该实例继承httpclient实现https通讯;
5、TLS是SSL 3.0的升级版;
https相关文件说明:
1、xxx.keystore // 服务器证书库,配置在web服务端,tomcat的server.xml中;
2、xxxTrust.keystore // 客户端信任证书库,由服务端证书生产;
3、*.cer // 客户端证书,由客户端证书库导出;
4、*.cer // 服务端证书,由服务端证书库导出;
5、客户端证书库、服务器证书库都设置,表示双向验证,如果只传其中一个,表示单向数据传输验证;
6、https与http的代码不同之处,在于sslContext的获取;
相关jar包:
<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>
代码说明:
本实例只实现了https双向验证中的客户端验证,具体服务器端的验证和配置(主要是web服务器配置)这里不涉及
代码如下:
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.nio.charset.Charset; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import org.apache.commons.lang.StringUtils; import org.apache.http.HttpEntity; import org.apache.http.HttpStatus; import org.apache.http.NameValuePair; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.entity.ContentType; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.Htt 4000 pClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; public class HttpsUtil { /** * 默认字符集 */ private static final String defaultCharset = "UTF-8"; /** * 连接超时时间 */ private final static int connectionTimeout = 6000; /** * socket超时时间 */ private final static int soTimeout = 10000; // 主秘钥绝对路径 private static final String keystore = "xxx.keystore"; // 主密钥密码 private static final String keystorePassword = "xxxxxx"; // 信任密钥绝对路径 private static final String truststore = "xxxTrust.keystore"; // 信任密钥密码 private static final String truststorePassword = "xxxxxx"; private static SSLContext sslContext; /** * 从给定的路径中加载此 KeyStore * * @param filePath * keystore 文件绝对路径 * @param password * keystore 访问密钥 * @return keystore 对象 */ private static KeyStore createKeyStore(final String filePath, final String password) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException { if (filePath == null) { throw new IllegalArgumentException("证书路径为空!"); } KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType()); InputStream is = null; try { // is = new FileInputStream(new File(filePath)); is = HttpsUtil.class.getResourceAsStream(filePath); keystore.load(is, password != null ? password.toCharArray() : null); } finally { if (is != null) { is.close(); is = null; } } return keystore; } /** * Post方式提交,URL中不包含提交参数, 格式:http://www.g.cn * * @param url * 提交地址 * @param content * 提交内容 * @return 响应消息 */ public static String post(String url, String content) { return post(url, content, null); } /** * Post方式提交 * * @param url * 请求地址 * @param content * 请求内容,可为空 * @param charset * 字符集 * @return */ public static String post(String url, String content, String charset) { if (StringUtils.isBlank(url)) { return null; } if (charset == null) { charset = defaultCharset; } CloseableHttpClient httpclient = getHttpClient(); ByteArrayEntity entity = null; HttpPost httpPost = null; String result = null; try { httpPost = new HttpPost(url); if (!StringUtils.isBlank(content)) { entity = new ByteArrayEntity(content.getBytes(charset)); httpPost.setEntity(entity); } CloseableHttpResponse httpResponse = httpclient.execute(httpPost); StatusLine status = httpResponse.getStatusLine(); HttpEntity httpEntity = httpResponse.getEntity(); result = EntityUtils.toString(httpEntity); if (status.getStatusCode() == HttpStatus.SC_OK) { System.out.println("服务器返回【正常】:" + result); } else { System.out.println("服务器返回【异常】:" + result); return null; } } catch (IOException e) { e.printStackTrace(); } finally { if (httpclient != null) { try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } return result; } /** * Post方式提交,URL中不包含提交参数, 格式:http://www.g.cn * * @param url * 提交地址 * @param params * 提交参数集, 键/值对 * @return 响应消息 */ public static String post(String url, Map<String, String> params) { return post(url, params, null); } /** * Post方式提交,URL中不包含提交参数, 格式:http://www.g.cn * * @param url * 提交地址 * @param params * 提交参数集, 键/值对 * @param charset * 参数提交编码集 * @return 响应消息 */ public static String post(String url, Map<String, String> params, String charset) { if (StringUtils.isBlank(url)) { return null; } if (charset == null) { charset = defaultCharset; } CloseableHttpClient httpclient = getHttpClient(); String result = null; UrlEncodedFormEntity formEntity = null; try { if (StringUtils.isBlank(charset)) { formEntity = new UrlEncodedFormEntity(getParamsList(params)); } else { formEntity = new UrlEncodedFormEntity(getParamsList(params), charset); } } catch (UnsupportedEncodingException e) { e.printStackTrace(); return null; } HttpPost httpPost = new HttpPost(url); httpPost.setEntity(formEntity); try { CloseableHttpResponse httpResponse = httpclient.execute(httpPost); StatusLine status = httpResponse.getStatusLine(); HttpEntity httpEntity = httpResponse.getEntity(); result = EntityUtils.toString(httpEntity); if (status.getStatusCode() == HttpStatus.SC_OK) { System.out.println("服务器返回【正常】:" + result); } else { System.out.println("服务器返回【异常】:" + result); return null; } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (httpclient != null) { try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } return result; } /** * 将传入的键/值对参数转换为NameValuePair参数集 * * @param paramsMap * 参数集, 键/值对 * @return NameValuePair参数集 */ private static List<NameValuePair> getParamsList( Map<String, String> paramsMap) { if (paramsMap == null || paramsMap.size() == 0) { return null; } List<NameValuePair> params = new ArrayList<NameValuePair>(); for (Map.Entry<String, String> map : paramsMap.entrySet()) { params.add(new BasicNameValuePair(map.getKey(), map.getValue())); } return params; } /** * form请求,上传图片 * * @param datas * 普通数据map * @param files * 图片map * @param uploadUrl * 上传图片的地址 */ public static String postForm(Map<String, String> datas, Map<String, String> files, String uploadUrl) { CloseableHttpClient httpclient = getHttpClient(); HttpPost httpPost = new HttpPost(uploadUrl); String result = ""; RequestConfig requestConfig = RequestConfig.custom() .setSocketTimeout(soTimeout) .setConnectTimeout(connectionTimeout).build(); httpPost.setConfig(requestConfig); MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder .create(); multipartEntityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); multipartEntityBuilder.setCharset(Charset.forName(defaultCharset)); Set<Map.Entry<String, String>> setData = datas.entrySet(); Iterator<Map.Entry<String, String>> iterator = setData.iterator(); // 文本 while (iterator.hasNext()) { Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator .next(); multipartEntityBuilder.addTextBody( entry.getKey(), entry.getValue(), ContentType.create("text/plain", Charset.forName(defaultCharset))); } // 发送的文件 if (files != null) { iterator = files.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<String, String> entry = (Map.Entry<String, String>) iterator .next(); String path = entry.getValue(); if ("".equals(path) || path == null) continue; File file = new File(entry.getValue()); // addBinaryBody还支持字节流、文件流 multipartEntityBuilder.addBinaryBody(entry.getKey(), file); } } CloseableHttpResponse response = null; HttpEntity httpEntity = multipartEntityBuilder.build(); httpPost.setEntity(httpEntity); try { response = httpclient.execute(httpPost); StatusLine status = response.getStatusLine(); HttpEntity entity = response.getEntity(); result = EntityUtils.toString(entity); if (status.getStatusCode() == HttpStatus.SC_OK) { System.out.println("服务器返回【正常】:" + result); } else { System.out.println("服务器返回【异常】:" + result); return null; } } catch (ClientProtocolException e) { e.printStackTrace(); } catch (UnsupportedEncodingException e1) { e1.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } finally { if (httpclient != null) { try { httpclient.close(); } catch (IOException e) { e.printStackTrace(); } } } return result; } /** * 获取httpclient * * @return */ private static CloseableHttpClient getHttpClient() { if (sslContext == null) { try { // 客户端秘钥管理器 KeyManagerFactory kmf = KeyManagerFactory .getInstance("SunX509"); kmf.init(createKeyStore(keystore, keystorePassword), keystorePassword.toCharArray()); // init()验证数据 KeyManager[] keyManagers = kmf.getKeyManagers(); // 服务端秘钥管理器 TrustManagerFactory trustManagerFactory = TrustManagerFactory .getInstance("SunX509"); trustManagerFactory.init(createKeyStore(truststore, truststorePassword)); TrustManager[] trustManagers = trustManagerFactory .getTrustManagers(); sslContext = SSLContext.getInstance("TLS"); sslContext.init(keyManagers, trustManagers, new SecureRandom()); } catch (Exception e) { System.out.println("获取ssl证书异常!"); e.printStackTrace(); return null; } } SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory( sslContext, SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); return HttpClients.custom().setSSLSocketFactory(sslsf).build(); } }
相关文章推荐
- eclipse中使用Jetty插件实现https请求与SSL双向验证
- 使用Nginx实现HTTPS双向验证的方法
- Https请求忽略证书验证最新实现
- Tomcat双向Https验证搭建,亲自实现与主流浏览器、Android/iOS移动客户端超安全通信
- okhttp/Retrofit-rxJava加入数字证书支持HTTPS 实现单向及双向验证
- ASIHTTPRequest实现https双向认证请求
- ASIHTTPRequest实现https双向认证请求
- 关于Okhttp3 https双向验证实现代码
- ASIHTTPRequest实现https双向认证请求
- 详解iOS开发 - 用AFNetworking实现https单向验证,双向验证
- 使用Volley实现Https请求, Volley SSL 双向自认证证书请求。
- ASIHTTPRequest实现https双向认证请求
- 使用Nginx实现HTTPS双向验证的方法
- ASIHTTPRequest实现https双向认证请求
- AsyncHttpClient实现https,并且实现SSL双向验证
- 网络编程六:https请求(双向验证)
- ASIHTTPRequest实现https双向认证请求
- ASIHTTPRequest实现https双向认证请求
- ASIHTTPRequest实现https双向认证请求
- Https请求忽略证书验证最新实现