本文共 1644 字,大约阅读时间需要 5 分钟。
通过https协议,客户端与服务端可以建立加密的通道,防止通讯被监听和篡改。但是,有时会遇到在访问一些网站时,提示连接不安全的警告,或者使用某种编程语法发起http请求时,出现异常。
https为什么会变得不安全了呢?这是因为网站的证书不是安全的,更准确的说是,证书不是由CA颁发的。CA是Certificate Authority的缩写,也叫证书授权中心。常用CA的根证书默认已经安装在操作系统里了,使用这些CA颁发的证书的网站,在访问时就不会出现安全警告。否则,就会出现前面的这种情况,最常见的就是我们自签名的证书,这也是许多开发者经常遇到的现象。
在搜索引擎里搜索解决方案时,得到的最多解决方法就是忽略证书的验证。如代码1所示,创建一个TrustStrategy的子类,使方法isTrusted直接返回true。
SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { // 信任所有 @Override public boolean isTrusted(X509Certificate[] chain, String authType) { return true; }}).build();
代码1
代码1的方式可以解决无法建立https连接的问题,这段程序会忽略对证书的验证,问题虽然解决了,但是也带来了安全隐患。https证书是为了验证网站或服务器身份的合法性的,防止有人蓄意假冒。
本文介绍一种java环境使用真正自签证书进行https连接的而非跳过验证方式。
首先需要明白的是,出现无法建立安全连接的原因不是证书不存在,而是证书的签名机构的根证书不在当前的运行环境中,所以解决方法就是将证书安装到当前的运营环境。
首先,将服务器url输入到浏览器地址栏中。如图1。
图1
点击地址前面的锁图标,进入图2的界面。
图2
点击“复制到文件”,进入图3界面。
图3
最终将证书文件保存到本地文件中。
上面已经从浏览器导出了证书文件,现在证书是以一个独立的文件形式存在的。在java程序中如果想使用这个证书文件,还需要将它导入到jdk的秘钥库中。
Jdk秘钥库文件是%JAVA_HOME%/jre/lib/security/cacerts,%JAVA_HOME%是jdk的安装位置。在%JAVA_HOME%/jre/lib/security/目录下执行keytool, 如图4。密码输入changeit,这是秘钥库的默认密码。
图4
HttpClientBuilder builder = HttpClients.custom() .setDefaultRequestConfig(defaultRequestConfig); SSLContextBuilder contextBuilder = new SSLContextBuilder();contextBuilder.setProtocol("TLSv1.2");SSLContext sslContext = contextBuilder.build();SSLConnectionSocketFactory f = new SSLConnectionSocketFactory(sslContext); builder.setSSLSocketFactory(f);CloseableHttpClient httpclient = builder.build();
代码1
如代码1,证书被导入到jdk秘钥库后,就可以不用忽略信任证书。
转载地址:http://ujabb.baihongyu.com/