您的位置:首页 > 理论基础 > 计算机网络

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服务器配置)这里不涉及

代码如下:

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();
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: