目录
1.keystore与truststore区别
①keystore是存储公钥、私钥的容器;
②keystore和truststore其本质都是keystore,只不过二者盛放的密钥所有者不同而已;
③keystore一般存储自己的私钥和公钥,通常来说,就是服务器端使用keystore来存储自己的公钥和私钥;
④truststore则用来存储自己信任的对象的公钥,举个例子,浏览器Brower访问服务器Server,浏览器Brower存储来自服务器Server的公钥;
⑤单向认证:由于单向认证是客户端去验证服务器端的真伪性,所以需要将服务器端的证书导出,导出的证书就是服务器端的公钥。然后将证书导入到客户端的truststore中,这样服务器就被客服端信任了,连接时客户端使用服务器端的公钥去验证服务器;
⑥双向认证:服务器的公钥导入到客户端的truststore,而客户端的公钥导入到服务器端的truststore中;
2.HTTPS工作流程
TLS/SSL协议使用了非对称加密、对称加密、HASH算法,握手过程的具体描述如下:
1)浏览器将自己支持的一套加密规则发送给网站。
2)网站从中选出一组加密算法与HASH算法,并将自己的身份信息以证书的形式发回给浏览器。证书里面包含了网站地址,加密公钥,以及证书的颁发机构等信息。(加密算法负责加密,HASH算法负责防篡改)
3)浏览器获得网站证书之后浏览器要做以下工作:
a)验证证书的合法性(颁发证书的机构是否合法,证书中包含的网站地址是否与正在访问的地址一致等),如果证书受信任,则浏览器栏里面会显示一个小锁头,否则会给出证书不受信的提示。
b)如果证书受信任,或者是用户接受了不受信的证书,浏览器会生成一串随机数的密码,并用证书中提供的公钥加密。(浏览器端用公钥加密,服务器端用私钥解密)
c)使用约定好的HASH算法计算握手消息,并使用生成的随机数对消息进行加密,最后将之前生成的所有信息发送给网站。
4)网站接收浏览器发来的数据之后要做以下的操作:
a) 使用自己的私钥将信息解密取出密码,使用密码解密浏览器发来的握手消息,并验证HASH是否与浏览器发来的一致。
b) 使用密码加密一段握手消息,发送给浏览器。
5)浏览器解密并计算握手消息的HASH,如果与服务端发来的HASH一致,此时握手过程结束,之后所有的通信数据将由之前浏览器生成的随机密码并利用对称加密算法进行加密。
3.keytool命令
keytool
-genkey
-alias tomcat(别名)
-keypass 123456(别名密码)
-keyalg RSA(生证书的算法名称,RSA是一种非对称加密算法)
-keysize 1024(密钥长度,证书大小)
-validity 365(证书有效期,天单位)
-keystore W:/tomcat.keystore(指定生成证书的位置和证书名称)
-storepass 123456(获取keystore信息的密码)
-storetype (指定密钥仓库类型)
4.不同格式文件的区别
.DER/.CER | 文件是二进制格式,只保存证书,不保存私钥 |
.PEM | 一般是文本格式,可以保存证书,也可以保存私钥 |
.CRT | 可以是二进制格式,可以是文本格式,与.DER 格式相同,不保存私钥 |
.PFX/.P12 | 二进制格式,同时包含证书和私钥,一般有密码保护 |
.JKS | 二进制格式,同时包含证书和私钥,一般有密码保护 |
5.单向认证开发步骤(信任所有证书、主机)
5.1.开发思路
按照HTTPS流程,客户端需要验证如下内容:验证拿到的证书,是我想要的特定服务器的证书;
那既然这样,我在重写的时候,只需永远返回true就代表着我信任任何证书;
5.2.客户端代码
public static CloseableHttpClient createSSLClientDefault() { try { //使用 loadTrustMaterial() 方法实现一个信任策略,信任所有证书 SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy() { // 信任所有 public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException { return true; } }).build(); //NoopHostnameVerifier类: 作为主机名验证工具,实质上关闭了主机名验证,它接受任何 //有效的SSL会话并匹配到目标主机。 HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE; SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); return HttpClients.custom().setSSLSocketFactory(sslsf).build(); } catch (KeyManagementException e) { log.info(e); } catch (NoSuchAlgorithmException e) { log.info(e); } catch (KeyStoreException e) { log.info(e); }catch (Exception e) { log.info(e); } return HttpClients.createDefault(); } |
5.3.SpringBoot配置
server: |
5.4.Postman配置信任所有证书
5.6.个人总结
刚面对配置HTTPS的时候,我定的方向错了,我以为SpringBoot对外提供HTTPS服务的时候,需要让SpringBoot自己来信任所有证书,因此,白白浪费了2021-05-11、2021-05-12这2天的时间,哎,学艺不精,没有深刻理解HTTPS的逻辑,往后学习某个知识点,要明白其中的内部原理,这样才能随时可以再次使用,让之前的失误成为后续成功的材料;