Java HTTPS客户端如何处理证书


HTTPS(HTTP over Secure Socket Layer),简单讲即HTTP下加入SSL层,HTTPS的安全基础是SSL。


参考以前的两篇文章
Java-JSSE-SSL/TLS编程代码实例-单向认证 
Java-JSSE-SSL/TLS编程代码实例-双向认证 
如果要实现SSL通讯,通讯双方需要设置KeyStore和TrustStore。
如果是单向认证,那么client侧只需要设置TrustStore, 客户端的TrustStore文件中保存着被客户端所信任的服务器的证书信息。

客户端在进行SSL连接时,JSSE将根据这个文件中的证书决定是否信任服务器端的证书。


但是通常我们并不需要做这个就能正常访问HTTPS服务。比如利用Spring中的RestTemplate访问微信的获取AccessToken的API接口。
    @Test
    public void testRestTemplate() throws Exception {
        String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=1&secret=2";
        RestTemplate restTemplate = new RestTemplate();
        String resultJasonStr = restTemplate.getForObject(url, String.class);
        System.out.println(resultJasonStr);
    }


运行成功,我们可以看到打印出来的返回结果,因为我们用的appid和secret都是错误的,所以会得到40001错误。
{"errcode":40001,"errmsg":"invalid credential, access_token is invalid or not latest hint: [v_xuha0307vr18]"}


如果不用Spring,也可以直接使用Java的java.net.URLConnection,会得到同样的结果
    @Test
    public void testHttpUrlConnection() throws IOException, URISyntaxException {
        URL url = new URL("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=1&secret=2");


        URLConnection con = url.openConnection();
        con.connect();
        BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"));
        String s;
        while ((s = reader.readLine()) != null) {
            System.out.println(s);
        }
        reader.close();
    }


为什么不需要设置TrustStore,HTTPS客户端就能正常工作呢?
首先要说明,TrustStore文件中也可以不保存服务器的证书信息,如果服务器的证书是经过CA签名的,那么只要保存着CA的根证书即可。
在SunJSSE中,有一个信任管理器类负责决定是否信任远端的证书,这个类有如下的处理规则:
1)若系统属性javax.net.ssl.trustStore指定了TrustStore文件,那么信任管理器就去jre安装路径下的lib/security/目录中寻找并使用这个文件来检查证书。
2)若该系统属性没有指定TrustStore文件,它就会去JRE安装路径下寻找默认的TrustStore文件,这个文件的相对路径为:lib/security/jssecacerts。
3)若jssecacerts不存在,但是cacerts存在(它随JRE一起发行,含有数量有限的可信任的基本证书),那么这个默认的TrustStore文件就是lib/security/cacerts。
按照这个规则,我们猜测,在JRE的jssecacerts或者是cacerts保存着微信API服务器证书的CA证书。


本机所使用的JDK1.8的jre/lib/security/下面找到了cacerts文件,
首先查看一下里面的证书。访问TrustStore文件需要store password, 默认的password是changeit.
C:\Program Files\Java\jdk1.8.0_45\jre\lib\security>keytool -list  -keystore cacerts -storepass changeit


密钥库类型: JKS
密钥库提供方: SUN


您的密钥库包含 92 个条目


digicertassuredidrootca, 2008-4-16, trustedCertEntry,
证书指纹 (SHA1): 05:63:B8:63:0D:62:D7:5A:BB:C8:AB:1E:4B:DF:B5:A8:99:B2:4D:43
trustcenterclass2caii, 2008-4-29, trustedCertEntry,
证书指纹 (SHA1): AE:50:83:ED:7C:F4:5C:BC:8F:61:C6:21:FE:68:5D:79:42:21:15:6E
thawtepremiumserverca, 2009-12-12, trustedCertE
  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值