keytool制作CA根证书以及颁发二级证书

步骤一:环境准备

1)电脑中部署好以下环境

        Tomcat:apache-tomcat-9.0.11

        JDK:jdk1.8.0_144

     通过地址:http://localhost:8080/   可以正常访问tomcat的猫猫头。

2)tomcat启用https协议功能(后面步骤会介绍如何生成秘钥)

    修改server.xml文件(apache-tomcat-9.0.11\conf),配置https连接器:

    释放掉https连接器

keytool制作CA根证书以及颁发二级证书

  修改https连接器内容,包含端口号、秘钥库文件路径,以及配置秘钥的口令(就是再生成秘钥文件时设置的口令)

keytool制作CA根证书以及颁发二级证书

备注:浏览器访问8080端口的连接器时,会以加密的方式来访问web服务器,连接器收到浏览器的请求后,会向浏览器出示一份数字证书,浏览器再用数字证书里面的公钥来加密数据, certificateKeystoreFile="tomcat11.keystore"用来指明**库文件的所在路径,服务器从**库中提取证书时需要密码,certificateKeystorePassword="123456"指明**库的访问密码。(tomcat8及8一下的版本配置的是keystoreFile="conf/.keystore"和keystorePass="123456")

3)启动tomcat,使用https://localhost:8080 进行访问测试。

步骤二:理论知识

1)HTTPS简介

超文本传输安全协议(英语:Hypertext Transfer Protocol Secure,缩写:HTTPS,常称为HTTP over TLS,HTTP over SSL或HTTP Secure)是一种网络安全传输协议。具体介绍以前先来介绍一下以前常见的HTTP,HTTP就是我们平时浏览网页时候使用的一种协议。HTTP协议传输的数据都是未加密的,也就是明文,因此使用HTTP协议传输隐私信息非常不安全。HTTP使用80端口通讯,而HTTPS占用443端口通讯。在计算机网络上,HTTPS经由超文本传输协议(HTTP)进行通信,但利用SSL/TLS来加密数据包。HTTPS开发的主要目的,是提供对网络服务器的身份认证,保护交换数据的隐私与完整性。

HTTPS其实是有两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块,并且会进行身份的验证。

SSL(Secure Sockets Layer 安全套接层)是为网络通信提供安全及数据完整性的一种安全协议,SSL在网络传输层对网络连接进行加密,SSL协议位于TCP/IP协议与各种应用层协议之间,为数据通信提供安全支持。SSL协议分为两层,SSL记录协议建立在TCP之上,为高层协议提供数据封装、压缩、加密等基本功能支持。SSL握手协议建立在SSL记录协议之上,用户实际数据传输开始前进行身份验证、协商加密算法、交换加密秘钥。

问题:Firebug和postman之类的浏览器调试工具,为什么获取到的是明文?

解答:

SSL是对传输的数据进行加密,针对的是传输过程的安全。 

firebug之类的浏览器调试工具,因为他们得到的是客户端加密之前/解密之后的数据,因此是明文的。

2)HTTPS工作原理

keytool制作CA根证书以及颁发二级证书

3)自签名证书简介

  • JDK中keytool是一个证书管理工具,可以生成自签名证书。 就是自己生成的证书,并不是官方生成的证书。除非是很正式的项目,否则使用自己签发的证书即可,因为官方生成证书是要花钱滴。

  • 其他描述

  • a)客户端发起HTTPS请求

  • 这个没什么好说的,就是用户在浏览器里输入一个https网址,然后连接到server的443端口。

  • b) 服务端的配置

  • 采用HTTPS协议的服务器必须要有一套数字证书,可以自己制作,也可以向组织申请。区别就是自己颁发的证书需要客户端验证通过,才可以继续访问,而使用受信任的公司申请的证书则不会弹出提示页面(startssl就是个不错的选择,有1年的免费服务)。这套证书其实就是一对公钥和私钥。如果对公钥和私钥不太理解,可以想象成一把钥匙和一个锁头,只是全世界只有你一个人有这把钥匙,你可以把锁头给别人,别人可以用这个锁把重要的东西锁起来,然后发给你,因为只有你一个人有这把钥匙,所以只有你才能看到被这把锁锁起来的东西。

  • c) 传送证书

  • 这个证书其实就是公钥,只是包含了很多信息,如证书的颁发机构,过期时间等等。

  • d)客户端解析证书

  • 这部分工作是有客户端的TLS来完成的,首先会验证公钥是否有效,比如颁发机构,过期时间等等,如果发现异常,则会弹出一个警告框,提示证书存在问题。如果证书没有问题,那么就生成一个随即值。然后用证书对该随机值进行加密。就好像上面说的,把随机值用锁头锁起来,这样除非有钥匙,不然看不到被锁住的内容。

  • e)传送加密信息

  • 这部分传送的是用证书加密后的随机值,目的就是让服务端得到这个随机值,以后客户端和服务端的通信就可以通过这个随机值来进行加密解密了。

  • f)服务段解密信息

  • 服务端用私钥解密后,得到了客户端传过来的随机值(私钥),然后把内容通过该值进行对称加密。所谓对称加密就是,将信息和私钥通过某种算法混合在一起,这样除非知道私钥,不然无法获取内容,而正好客户端和服务端都知道这个私钥,所以只要加密算法够彪悍,私钥够复杂,数据就够安全。

  • g)传输加密后的信息

  • 这部分信息是服务段用私钥加密后的信息,可以在客户端被还原

  • h)客户端解密信息

  • 客户端用之前生成的私钥解密服务段传过来的信息,于是获取了解密后的内容。整个过程第三方即使监听到了数据,也束手无策。

 步骤三:生成证书

keytool是jdk自带的一款ssl管理工具,keytool  --help看帮助信息。

1)生成自签名根证书
执行命令:keytool -genkeypair -alias trootca -keyalg RSA -keystore E:/workspace/apereo-cas/certificate/1/rootca.keystore

然后按照提示输入

输入**库口令:  
再次输入新口令: 
您的名字与姓氏是什么?
  [Unknown]:  xx认证中心
您的组织单位名称是什么?
  [Unknown]:  xx认证中心
您的组织名称是什么?
  [Unknown]:  xx认证中心
您所在的城市或区域名称是什么?
  [Unknown]:  杭州
您所在的省/市/自治区名称是什么?
  [Unknown]:  杭州
该单位的双字母国家/地区代码是什么?
  [Unknown]:  CN
CN=xx认证中心, OU=xx认证中心, O=xx, L=zz, ST=gd, C=CN是否正确?
  [否]:  Y

输入 <rootca> 的**口令
    (如果和**库口令相同, 按回车): 

alias是别名,就是给某某证书取个名字,可以随便写,可以用changealias命令修改
keyalg是加密算法,有DSA,RSA,默认是DSA,因为DSA只能用于加密,不能用户证书签名,所以这里必须指定使用RSA算法

这里有两个密码:**库密码和**密码,**库是存储**的地方,他有密码;只有知道这个密码才可以访问这个**库;**密码用于生产**。

如果**库不存在,则会使用输入的密码创建一个**库。**密码可以和**库密码一样。

因为我是用的tomcat做实验,这里有点问题,**库密码和**密码不一致会导致tomcat启动不了,报错提示密码错误(canot recover key),不知道是不是tomcat的bug,没有去验证,反正密码一样就不报错了。

命令执行成功后,如果没有指定keystore指定的位置,默认会在用户的home目录下生成.keystore文件,可以使用-keystore 参数指定生成的地址

这样就生成了一个自签名的根证书

2)用下列命令查看生成的结果

keytool -list -v -keystore E:/workspace/apereo-cas/certificate/1/rootca.keystore

可以看到这个证书的所有者和发布者都是xx认证中心,这就叫自签名.CA根证书都是自签名的

再生产一个自签名的证书,后面用前面这个rootca来签名这个证书,这样这个证书就不是自签名的证书,而是得到xx认证中心认证的证书了

3)生成二级的自签名证书
keytool -genkeypair -alias ttomcatcas -keyalg RSA -keystore E:/workspace/apereo-cas/certificate/1/rootca.keystore

输入**库口令:  
您的名字与姓氏是什么?
  [Unknown]:  codecrazy.com
您的组织单位名称是什么?
  [Unknown]:  XX技术有限公司
您的组织名称是什么?
  [Unknown]:  XX技术有限公司
您所在的城市或区域名称是什么?
  [Unknown]:  杭州
您所在的省/市/自治区名称是什么?
  [Unknown]:  杭州
该单位的双字母国家/地区代码是什么?
  [Unknown]:  CN
CN=www.baidu.com, OU=百度技术有限公司, O=百度技术有限公司, L=背景, ST=北京, C=CN是否正确?
  [否]:  Y

输入 <baidu> 的**口令
    (如果和**库口令相同, 按回车): 

 

现在假设我们是XX技术有限公司,我们需要申请一个证书,如上,我们生成了一个叫XX的自签名证书,但是XX的信用很差,广大网友不认可XX的信誉,所以XX的证书要到xx认证中心去认证。

先通过这个自签名证书生成一个证书请求

3.生成证书请求
keytool -certreq -alias ttomcatcas -keystore E:/workspace/apereo-cas/certificate/1/rootca.keystore -file E:/workspace/apereo-cas/certificate/1/tomcatcas.csr

这样就生成了一个证书请求文件tomcatcas.csr。然后我们拿着这个文件和钱去xx认证中心

4.去测试认证中心认证

keytool -gencert -alias trootca -keystore E:/workspace/apereo-cas/certificate/1/rootca.keystore -infile E:/workspace/apereo-cas/certificate/1/tomcatcas.csr -outfile E:/workspace/apereo-cas/certificate/1/tomcatcas.cer

tomcatcas.cer就是经过认证中心认证的证书了。XX拿着这个证书就回家了,然后把这个证书导入**库。证书的发布者就变成了xx认证中心


5.导入认证后的证书

keytool -importcert -alias ttomcatcas -keystore E:/workspace/apereo-cas/certificate/1/rootca.keystore -file E:/workspace/apereo-cas/certificate/1/tomcatcas.cer


6.查看结果

keytool -list -v -keystore E:/workspace/apereo-cas/certificate/1/rootca.keystore可以看到,发布者已经变成xx认证中心了。
这里有几点要注意,导入的**库必须是之前生成证书请求的**库,并且alias也要和之前一样。因为证书只包含公钥,而私钥在**库,所以必须导入之前生成证书请求的**库,并且alias必须和之前相同,这样才知道这个证书属于哪个别名。之前不知道这个概念,把证书导入到新的**库,导致做https的时候出错

我们用浏览器访问https网站,有些会提示不安全,有些不会,为什么呢?那些不会提示的是因为他们用的是第三方权威机构认证的证书,而我们系统已经内置了很多权威机构的根证书。只要系统信任某个根证书,由此根证书签发的二级证书也会被系统信任。

刚才我们生成的CA根证书是不被系统信任的,所以我们要导出rootca的证书,并安装到系统中,这样由rootca签发的证书都会被信任。

7.导出根证书,客户端进行信任配置

keytool -exportcert -alias trootca -keystore E:/workspace/apereo-cas/certificate/1/rootca.keystore -file E:/workspace/apereo-cas/certificate/1/rootca.cer

 把rootca.cer交给客户端,并导入系统,这样客户端浏览器访问我们的网站就不会提示不安全了。

将证书填入到“受信任的根证书颁发机构”。具体方法:(我用的谷歌浏览器):

- 打开谷歌浏览器 --> 设置--> 高级 --> 管理证书 --> 中级证书颁发机构 --> 选择www.seeker.com,点击导出到桌面SEEKER.cer

- 打开谷歌浏览器 --> 设置--> 高级 --> 管理证书 --> 受信任的根证书颁发机构 --> 导入SEEKER.cer


其他浏览器将证书填入到“受信任的根证书颁发机构”:

- 打开浏览器   - 工具  -  internet选项-内容- 证书-把中级证书颁发机构里的www.seeker.com(该名称即时你前面生成证书时填写的名字与姓氏)证书导出来-再把导出来的证书导入  受信任的根颁发机构  就OK了。

遇到问题:

chrome浏览器,不管怎么折腾一直提示证书有效,但是无法使用的问题。采用IE浏览器没有这个问题存在