日常记录

背景

近期项目上由于要把服务器部署在公网上,所有提出需要对通讯加密和身份认证
主要是想记录下来

环境

客户端使用httpclient
服务端使用netty
其实使用什么都是一个原理,😄

原理

双向认证原理大家应该都知道差不多,主要是
1.服务端校验客户端的签名和根证书
2.客户端校验服务端的签名和根证书

HttpClient

package demo.httpclient;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManagerFactory;
import org.apache.http.HttpEntity;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;
import org.apache.http.ssl.TrustStrategy;
import org.apache.http.util.EntityUtils;
import demo.aa.ContextSSLFactory;
@SuppressWarnings(“unused”)
public class HttpClentUtils {
private static final String HTTP = “http”;
private static final String HTTPS = “https”;
private static SSLConnectionSocketFactory sslsf = null;
private static SSLContext sslContext = null;
private static PoolingHttpClientConnectionManager cm = null;
private static RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(120000)
.setSocketTimeout(120000).setConnectTimeout(120000).build();

static {
try {
KeyStore keyStore = KeyStore.getInstance(“JKS”);
String pd = “111111”;
keyStore.load(new FileInputStream("/client.keystore"), pd.toCharArray());
sslContext = new SSLContextBuilder().loadKeyMaterial(keyStore, pd.toCharArray())
.loadTrustMaterial(keyStore, null
// sslContext = new SSLContextBuilder().loadKeyMaterial(keyStore,
// pd.toCharArray()).loadTrustMaterial(keyStore, new TrustSelfSignedStrategy()
/{
@Override
public boolean isTrusted(
final X509Certificate[] chain, final String authType) throws CertificateException {
String string = new String(com.sun.org.apache.xerces.internal.impl.dv.util.Base64.encode(chain[0].getEncoded()));
System.out.println(string);
return chain.length == 1;
}
}
/
).build();
// 加载客户端证书
sslContext = ContextSSLFactory.getSslContext2();
sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Registry registry = RegistryBuilder.create()
.register(HTTP, new PlainConnectionSocketFactory()).register(HTTPS, sslsf).build();
cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(200);// max connection
} catch (Exception e) {
e.printStackTrace();
}
}

public static void doPostTestOne() throws Exception {
// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
CloseableHttpClient httpClient = HttpClients.custom().evictExpiredConnections()
.evictIdleConnections(60, TimeUnit.SECONDS).setSSLSocketFactory(sslsf).setConnectionManager(cm)
.setConnectionManagerShared(true).build();
// 创建Post请求
HttpPost httpPost = new HttpPost(“https://127.0.0.1:8886”);
httpPost.addHeader(“connection”, “Keep-Alive”);
httpPost.setConfig(requestConfig);
// 响应模型
CloseableHttpResponse response = null;
try {
// 由客户端执行(发送)Post请求
response = httpClient.execute(httpPost);
// 从响应模型中获取响应实体
HttpEntity responseEntity = response.getEntity();
if (responseEntity != null) {
System.out.println(“响应内容为:” +response.getStatusLine() + EntityUtils.toString(responseEntity));
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 释放资源
if (httpClient != null) {
httpClient.close();
}
if (response != null) {
response.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

netty

不想记录了

心得

主要想记录的是这个,在通讯认证时候,需要校验对方的根证书
1.一种是交给信任SSLContext的信任管理器 上面代码就是
2.而是我们可以自己实现

static {
try {
KeyStore keyStore = KeyStore.getInstance(“JKS”);
String pd = “111111”;
keyStore.load(new FileInputStream("/client.keystore"), pd.toCharArray());
sslContext = new SSLContextBuilder().loadKeyMaterial(keyStore, pd.toCharArray())
.loadTrustMaterial(keyStore, new TrustSelfSignedStrategy() {
@Override
public boolean isTrusted(final X509Certificate[] chain, final String authType)
throws CertificateException {
//这里我们可以获取到对方传过来的公钥证书
//我们可以自己实现信任管理器校验
List caList = new ArrayList();
//这里需要使用ca证书验证公钥证书里面的签名信息有服务的就返回true,否则false校验不通过
return true;
}
}).build();
// 加载客户端证书
sslContext = ContextSSLFactory.getSslContext2();
sslsf = new SSLConnectionSocketFactory(sslContext, SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
Registry registry = RegistryBuilder.create()
.register(HTTP, new PlainConnectionSocketFactory()).register(HTTPS, sslsf).build();
cm = new PoolingHttpClientConnectionManager(registry);
cm.setMaxTotal(200);// max connection
} catch (Exception e) {
e.printStackTrace();
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值