Https证书生成及配置介绍

在上一篇文章Https介绍及Wireshark演示我们对https有了一个基本的了解,也可以通过wireshark可以清晰的看到https整个握手流程。本文我们继续https的介绍,主要是有关https证书相关的知识点,如公钥、私钥以及数字签名,通过JDK提供的工具类keytool生成一个https证书,并通过tomcat示例介绍如何使用证书部署https。对于各种对称非对称加密算法本文暂不做介绍。

公钥、私钥以及数字签名

公钥

公钥(Public Key)与私钥(Private Key)是通过同一种算法得到的一个密钥对。公钥是密钥对中公开的部分,私钥则是非公开的部分。公钥通常用于加密会话密钥、验证数字签名,或加密可以用相应的私钥解密的数据。公钥之所以可以公开,主要是基于公钥密码体制,也是非对称密码体制。在这种体制下,不仅加密算法本身可以公开,甚至加密用的密钥也可以公开。但这并不意味着保密程度的降低。因为加密密钥和解密密钥不一样。

私钥

上面提到的在非对称密码体制下,公钥得以公开,与公钥对应的就是私钥。当然了在对称加密算法使用的密钥也称为私钥,这种机制是使用一把钥匙即可以加密也可以解密,本文所说的私钥可以直接理解为是非对称加密体制下的私钥。

  • 公钥和私钥成对出现;
  • 用公钥加密的数据只有对应的私钥可以解密;
  • 用私钥加密的数据只有对应的公钥可以解密;
  • 如果可以用公钥解密,则必然是对应的私钥加的密;
  • 如果可以用私钥解密,则必然是对应的公钥加的密。

数字签名

根据上面公钥的介绍,公钥可以验证数字签名,这里也可以理解为公钥可以解密数字签名。在私钥中我们解释说了,如果公钥可以解密,则必然是私钥加密的。因此数字签名即是用私钥加密的数据。

这里列举一个简单示例解释公钥私钥以及数字签名。假设A、B、C与D可以相互进行通信,A使用秘钥算法获取到了自己的私钥以及可以公开的公钥,并将公钥发送给了B、C、D。这时候B使用A的公钥发送数据,即使C或者D接收到数据后也无法确认报文的详细信息,因为他们没有A的私钥所以无法解密。A继续发送报文,这次报文使用的是自己的私钥加密的数据。B、C以及D接收到报文后,发现可以使用A的公钥解密信息,于是可以确认这条报文就是A发来的,后面这个过程就可以认为是数字签名的实现。

数字签名不仅可以确认发送方的身份,同样还可以确保消息的完整性,因为在发送过程中会将报文摘要进行加密作为数字签名和报文一起发送给接收方。接收方接收到报文后,首先使用发送方公钥进行解密,如果报文摘要一样,说明在传输过程中报文没有被更改过,也可以确认确实是发送发发送的报文。

https证书介绍

在非对称加密体制下,由于加密算法可以公开,公钥也可以公开,在这个前提下任何人都可以使用加密算法获取公钥私钥,但是却无法确认公钥是谁签发的。那么用户在使用过程中就无法确保自己的数据是传输到了可信任的另一端。为了解决上述问题,数字证书应运而生。一般数字证书包括如下信息:

  • 证书的发布机构
  • 证书的有效期
  • 公钥
  • 证书所有者(Subject)
  • 签名所使用的算法
  • 指纹以及指纹算法

数字证书可以保证数字证书里的公钥确实是这个证书的所有者(Subject)的,或者证书可以用来确认对方的身份。也就是说,我们拿到一个数字证书,我们可以判断出这个数字证书到底是谁的。

常用的证书格式

在开发中常见的证书有关的扩展名包括pem、crt、cer、der、pfx、p12以及key,这里多数格式都以文本格式存储的,可以直接用文本文件打开,通用格式如下:

-----BEGIN CERTIFICATE-----

Base64编码过的证书数据

-----END CERTIFICATE-----
  • pem privacy enhanced mail缩写,证书文件一般是文本格式,可以存放证书或私钥,或者两者都包含。 *.PEM 文件如果只包含私钥,一般用 *.KEY 文件代替;
  • der distinguished encoding rules缩写,以二进制方式进行存储,文件结构无法直接预览;
  • crt certificate缩写,常见于类UNIX系统,有可能是pem编码,也有可能是der编码,但绝大多数情况下此格式证书都是采用pem编码;
  • cer certificate缩写,常见于Windows系统,同样地,可能是pem编码,也可能是der编码,但绝大多数情况下此格式证书都是采用der编码;
  • p12 也称作pfx,公钥加密标准(Public Key Cryptography Standards,PKCS)系列的一种,可能是pem编码,也可能是der编码,同时包含证书和私钥,且一般有密码保护。

通过JDK的keytool生成证书

keytool是Java用于管理密钥和证书的工具,采用keystore件来存储密钥及证书,其中可包括私钥、信任证书。keystore文件主要使用JKS格式(也可支持其他格式),带密钥存储;其中私钥的存储也有独立的密码。

keytool的常用命令如下:

-certreq            生成证书请求
-changealias        更改条目的别名
-delete             删除条目
-exportcert         导出证书
-genkeypair         生成密钥对
-genseckey          生成密钥
-gencert            根据证书请求生成证书
-importcert         导入证书或证书链
-importpass         导入口令
-importkeystore     从其他密钥库导入一个或所有条目
-keypasswd          更改条目的密钥口令
-list               列出密钥库中的条目
-printcert          打印证书内容
-printcertreq       打印证书请求的内容
-printcrl           打印 CRL 文件的内容
-storepasswd        更改密钥库的存储口令

上面的格式是jdk1.8中的命令格式,在老的版本中可能有所不同,如-genkeypair-exportcert在以旧版本中分别是-genkey-export。不过在使用上面没有差异,命令在新版本JDK中也是通用的。

生成单向认证证书

生成keystore -validity对应的是天数
keytool -genkeypair -v -alias tomcat -keyalg RSA -storetype PKCS12 -keystore E:\keystore\tomcat.keystore -validity 36500 

导出证书
keytool -exportcert -alias tomcat -keystore E:\keystore\tomcat.keystore -storetype PKCS12 -storepass 123456 -rfc -file E:\keystore\tomcat.cer

查看keystore信息
keytool -list -v -keystore E:\keystore\tomcat.keystore

打印证书信息
keytool -printcert -file E:\keystore\tomcat.cer

生成双向认证证书

首先按照上面相同的方式生成server.keystore和client.keystore。双向认证必须把客户端证书添加为服务器的信任认证。由于不能直接将PKCS12格式的证书库导入,必须先把客户端证书导出为一个单独的cer文件。在生成双向认证证书时有一点需要注意的地方,您的名字与姓氏是什么?这一步一定要输入服务器的地址,如果是域名则输入域名,否则输入IP地址,这里使用的是localhost本机地址,在后面确认时对应CN的值。

导出一个client证书
keytool -exportcert -alias client -keystore E:\keystore\client.p12 -storetype PKCS12 -storepass 123456 -rfc -file E:\keystore\client.cer

导出一个server证书给客户端
keytool -exportcert -alias server -keystore E:\keystore\server.keystore -storetype PKCS12 -storepass 123456 -rfc -file E:\keystore\server.cer

将client证书导入server的证书库keystore
keytool -importcert -v -file E:\keystore\client.cer -keystore E:\keystore\server.keystore

在进行双向认证配置时server.keystore放在服务端即可, 客户端需要client.p12和server.cer两个证书文件。

tomcat部署https证书

打开Tomcat根目录下的/conf/server.xml,找到Connector port="8443"配置段,一般8443这个端口配置都注释掉了,将注释剔除即可。

配置单向认证。

<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
			   keystoreFile="E:\keystore\tomcat.keystore"
			   keystorePass="123456"/> 

配置双向认证。

<Connector port="8443" protocol="org.apache.coyote.http11.Http11Protocol"
		   maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
		   clientAuth="true" sslProtocol="TLS"
		   keystoreFile="E:\keystore\server.keystore" keystorePass="123456"
		   truststoreFile="E:\keystore\server.keystore" truststorePass="123456"/>

属性说明:

  • clientAuth:设置是否双向验证,默认为false,设置为true代表双向验证;
  • keystoreFile:服务器证书文件路径;
  • keystorePass:服务器证书密码;
  • truststoreFile:用来验证客户端证书的根证书,此例中就是服务器证书;
  • truststorePass:根证书密码;

在双向验证配置完成后需要将上面生成的证书安装在客户端,在没有安装证书时,打开浏览器会有类似如下提示:

先点击安装客户端证书库client.p12,直接按照提示一步步按照即可。为避免每次都提示不安全,在双击安装server.cer服务器证书,注意将证书填入到“受信任的根证书颁发机构

再次打开IE浏览器既可以看到标记性的锁标记,这时候就表明双向认证已经完成。

有关https的介绍到这里已经介绍2篇博文了,对https应该有了更进一步的理解了。在本文中介绍了公私钥以及证书相关内容,并使用keytool生成了https证书,在tomcat上面也可以配置完成,通过了浏览器的安全验证。下一篇将继续介绍如何在Android上使用https,即使用Java代码实现https的通信。有关https介绍通过3篇博文已经可以满足日常开发需要了,证书的申请一般都是服务器端提供,很少让Android终端开发自己申请,有兴趣的话可以继续研究一下openssl工具的使用。

参考资料

公钥

私钥

SSL证书

公钥,私钥和数字签名这样最好理解

数字证书原理

Tomcat服务器配置https双向认证(使用keytool生成证书)

评论

您确定要删除吗?删除之后不可恢复