java基础总结(三十二)--Https协议的使用--服务器端和客户端
说明
1:本文介绍了两个知识模块,一个是Tomcat配置SSL另外一个是客户端绕过证书验证实现https
2:本文参考的是https://blog.****.net/xiaoxian8023/article/details/49865335这个博客。而原博客中tomcat配置ssl是一篇博客,
客户端绕过证书验证实现https又是另外一篇博客。
为了方便我把原来博客中的tomcat配置ssl是一篇博客和客户端绕过证书验证实现https转载到我自己的****博客中
tomcat配置ssl:https://blog.****.net/lsx2017/article/details/86710102
客户端绕过证书验证实现https:
。
文章内容
1.Web服务器(tomcat)端配置
2.客户端(HttpClient)实现(Get/Post)
1.Web服务器(tomcat)端配置
1.1.服务器证书生成
使用keytool按照提示创建一个证书,如果以后真正在产品环境中使用肯定要去证书提供商去购买,证书认证一般都是由VeriSign认证,中文官方网站:http://www.verisign.com/cn/,需要注意一下几点:
1.**库口令
2.名字为网站域名(后面通过修改host转发)
命令:
keytool -genkey -alias aaronweb -keyalg RSA -keystore d:/keys/aaronweb
1.2.导出证书
导出的证书可以给响应的客户端使用
命令:
keytool -export -file d:/keys/waaronweb.crt -alias aaronweb -keystore D:/keys/aaronweb
1.3.创建私钥(pem)(用于tomcat apr模式)
命令:
keytool -importkeystore -srckeystore D:\keys\aaronweb -destkeystore D:\keys\aaronweb.p12 -deststoretype PKCS12openssl pkcs12 -in D:\keys\aaronweb.p12 -out D:\keys\aaronweb.pem -nodes
1.2.修改hosts文件
修改host使得在访问域名aaron.web.com时实际访问的是本地主机;
目录:C:\Windows\System32\drivers\etc\hosts
添加:127.0.0.1 aaron.web.com
1.3.Web服务器创建和配置
1.在Eclipse中配置好Tomcat环境,添加一个新的Web服务器;
2.修改服务器配置
修改Server.xml配置:
添加SSLCertificateFile(导出证书crt文件地址),SSLCertificateKeyFile(生成的私钥pem文件地址)
3.服务器测试
通过Eclipse导入一个Web项目到先添加的tomcat服务器上,启动服务器,在浏览器中测试;
注意端口地址8443或自定义
浏览器需要添加例外(证书不是公共平台认证的)
2.客户端(HttpClient)实现(Get/Post)
2.0.准备
应为需要测试Get、Post两种方式,需要在web项目中添加测试用的servlet,比如:
public class HelloWorldServlet extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
PrintWriter out = res.getWriter();
out.println("Hello, Brave new World!");
out.close();
}
}
2.1.忽略认证Https客户端的实现
在很多情况下我们并不希望验证服务器的证书信息,而需要忽略验证的结果,特别是在接口调用上,所以,首先实现忽略验证的Https客户端,主要实现常用的Get和Post方法;
下面是具体的步骤:
(对于其中涉及到的相关概念可以参考之前的文章:http://blog.****.net/villare/article/details/75045496)
1.首先我们继承默认的HttpClient父类,为了实现对上层的透明性,通过重写类的构造方法,完成对HttpClient的配置;
public class SSLClient extends DefaultHttpClient{
public SSLClient() throws Exception{
super();
}
}
2.由于Https为有状态的连接,所以首先需要设置上下文环境(Context),用于维护连接过程中的状态;Java提供与Https相关的Context类;
SSLContext ctx = SSLContext.getInstance("TLS");
3.由于我们需要忽略对证书的检查,所以需要实现X509TrustManager(证书信任管理器),重写器中的主要验证方法,达到忽略证书验证的目的;并配置到Context中
X509TrustManager tm = new X509TrustManager() {
//该方法检查客户端的证书,若不信任该证书则抛出异常
@Override
public void checkClientTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
//该方法检查服务器的证书,若不信任该证书同样抛出异常
@Override
public void checkServerTrusted(X509Certificate[] chain,
String authType) throws CertificateException {
}
//返回受信任的X509证书数组
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
//初始化Context
ctx.init(null, new TrustManager[]{tm}, null);
4.由于Https的数据传输为加密传输,一般的socket传输不考虑数据是否加密,当然HttpClient提供了相关的实现,只需要创建对应的SocketFactory对象,并绑定对应的Context;
SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
5.在当前HttpClient中注册Https模式,并绑定对应的SocketFactory;至此,通过此HttpCLient发送的Https请求就会使用当前SocketFactory和Context(包括其中的认证管理器);
ClientConnectionManager ccm = this.getConnectionManager();
SchemeRegistry sr = ccm.getSchemeRegistry();
sr.register(new Scheme("https", 8443, ssf));
6.在使用重写的SSLClient时,与普通的HttpClient一样;
HttpClient httpClient = new SSLClient();
2.2.检查认证Https客户端的实现
和忽略的方式唯一不同的是:证书认证管理器,如果忽略认证,我们在checkClientTrusted、checkServerTrusted和getAcceptedIssuers中都没有包含具体的验证逻辑或直接返回默认值;所以,如果需要验证证书,只需要在其中实现相应的逻辑即可,如果认证不通过,直接抛出CertificateException 异常即可,由于,证书不同,验证的方式也不同,具体的问题具体分析;