引言

本文主要讲述如何使用tomcat搭建https服务,主要内容有:

1 https协议基础和数字证书基础

2 基础环境准备

3 使用自签名证书配置tomcat

4 模拟使用CA认证的证书配置tomcat单向认证

5 配置tomcat双向认证

1 https协议基础和数字证书基础

https协议

参考维基百科定义:超文本传输安全协议(英语:HyperText Transfer Protocol Secure,缩写:HTTPS;常称为HTTP over TLS、HTTP over SSL或HTTP Secure)是一种通过计算机网络进行安全通信的传输协议。HTTPS经由HTTP进行通信,但利用SSL/TLS来加密数据包。HTTPS开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。这个协议由网景公司(Netscape)在1994年首次提出,随后扩展到互联网上。

历史上,HTTPS连接经常用于万维网上的交易支付和企业信息系统中敏感信息的传输。在2000年代末至2010年代初,HTTPS开始广泛使用,以确保各类型的网页真实,保护账户和保持用户通信,身份和网络浏览的私密性。

关键点:http协议本身不安全,https是在http协议基础上,增加一个SSL的传输层,用于保证http协议的安全

HTTPS = HTTP + SSL

数字证书

这里讲解一些基本概念:

公开密钥密码学/非对称式密码学

公开密钥密码学(英语:Public-key cryptography)也称非对称式密码学(英语:Asymmetric cryptography)是密码学的一种算法,它需要两个密钥,一个是公开密钥,另一个是私有密钥;公钥用作加密,私钥则用作解密。使用公钥把明文加密后所得的密文,只能用相对应的私钥才能解密并得到原本的明文,最初用来加密的公钥不能用作解密。由于加密和解密需要两个不同的密钥,故被称为非对称加密;不同于加密和解密都使用同一个密钥的对称加密。公钥可以公开,可任意向外发布;私钥不可以公开,必须由用户自行严格秘密保管,绝不透过任何途径向任何人提供,也不会透露给被信任的要通信的另一方。

关键点:用公钥加密,用私钥解密

上图来自《图解密码技术》一书

数字签名

数字签名(英语:Digital Signature,又称公钥数字签名)是一种功能类似写在纸上的普通签名、但是使用了公钥加密领域的技术,以用于鉴别数字信息的方法。一套数字签名通常会定义两种互补的运算,一个用于签名,另一个用于验证。法律用语中的电子签章与数字签名代表之意义并不相同。电子签章指的是依附于电子文件并与其相关连,用以辨识及确认电子文件签署人身份、资格及电子文件真伪者;数字签名则是以数学算法或其他方式运算对其加密而形成的电子签章。意即并非所有的电子签章都是数字签名。

数字签名不是指将签名扫描成数字图像,或者用触摸板获取的签名,更不是落款。

数字签名了的文件的完整性是很容易验证的(不需要骑缝章、骑缝签名,也不需要笔迹鉴定),而且数字签名具有不可抵赖性(即不可否认性),不需要笔迹专家来验证

关键点:

1 用私钥加密来生成签名,用公钥解密来验证签名

2 使用数字签名可以识别篡改和伪装,防止否认

上图来自《图解密码技术》一书

数字证书

公开密钥认证(英语:Public key certificate),又称数字证书(digital certificate)或身份证书(identity certificate)。是用于公开密钥基础建设的电子文件,用来证明公开密钥拥有者的身份。此文件包含了公钥信息、拥有者身份信息(主体)、以及数字证书认证机构(发行者)对这份文件的数字签名,以保证这个文件的整体内容正确无误。拥有者凭着此文件,可向电脑系统或其他用户表明身份,从而对方获得信任并授权访问或使用某些敏感的电脑服务。电脑系统或其他用户可以透过一定的程序核实证书上的内容,包括证书有否过期、数字签名是否有效,如果你信任签发的机构,就可以信任证书上的密钥,凭公钥加密与拥有者进行可靠的通信。

简而言之,认证机构用自己的私钥对需要认证的人(或组织机构)的公钥施加数字签名并生成证书,即证书的本质就是对公钥施加数字签名。

数字证书的其中一个最主要好处是在认证拥有者身份期间,拥有者的敏感个人数据(如出生日期、身份证号码等)并不会传输至索取数据者的电脑系统上。透过这种数据交换模式,拥有者既可证实自己的身份,亦不用过度披露个人数据,对保障电脑服务访问双方皆有好处。

X.509证书

X.509是数字证书的一个标准结构,

一般遵从X.509格式规范的证书,会有以下的内容,它们以字段的方式表示[12]:

例如维基百科证书

2 基础环境

基础环境:JDK8 + tomcat7

Jdk官网下载 https://www.oracle.com/java/technologies/javase-jdk8-downloads.html

tomcat官网下载 https://tomcat.apache.org/

具体安装这里不赘述

3 tomcat配置自签名证书

步骤1 生成证书

生成服务端密钥对

生成一个包含证书的密钥库文件,服务器可以使用该证书

简化cmd命令:

keytool -genkey -alias tomcat -keysize 2048 -validity 3650 -keyalg RSA -keystore tomcat.jks

命令说明(keytool -genkey --help):

-genkey 表示生成密钥对

-alias <alias> 要处理的条目的别名

-keyalg <keyalg> 密钥算法名称, 应该优先选择RSA算法作为安全算法,这还可以确保与其他服务器和组件的一般兼容性

-keysize <keysize> 密钥位大小

-validity <valDays> 有效天数

手动输入参数说明:

CN(您的名字与姓氏是什么?) 申请证书的域名

OU(您的组织名称是什么?) 申请单位的所在部门名称

O(您所在的城市或区域名称是什么?) 申请单位的所在公司名称

L(您所在的省/市/自治区名称是什么?)申请单位的所在城市

ST(您所在的省/市/自治区名称是什么?)申请单位的所在省份

C(该单位的双字母国家/地区代码是什么?)申请单位所属国家,ISO国家代码(两位字符)

其他说明:密钥库口令和密钥口令为了简单,设置为同一个默认密码changeit

也可以使用完整命令一次生成证书:

keytool -genkey -alias tomcat -keystore tomcat.jks -keypass changeit -storepass changeit -keyalg RSA -keysize 2048 -validity 365 -v -dname "CN = YWJ,OU = DevUI,O = DevCloud,L = ShenZhen,ST = GUANGDONG,C = CN"

查看证书

证书生成后,使用如下命令查看证书内容

keytool -list -v -keystore tomcat.jks

如果一切成功,那么您现在将拥有一个包含证书的密钥库文件,服务器可以使用该证书

步骤2 配置tomcat

修改%TOMCAT_HOME%/conf/server.xml

<!-- 自生成证书 -->

<Connector
  protocol="org.apache.coyote.http11.Http11NioProtocol"
  port="443" maxThreads="200"
  scheme="https" secure="true" SSLEnabled="true"
  keystoreFile="keystore\_guanwang/tomcat.jks"
  keystorePass="changeit"
  clientAuth="false" sslProtocol="TLS"
/>

4 模拟正式CA认证的证书配置tomcat单向认证

具备阶段

申请正式证书流程

首先,我们先生成如下证书文件

1 DevUI自身密钥库文件:devui.jks

keytool -genkey -alias devui -keystore devui.jks -keypass changeit -storepass changeit -keyalg RSA -keysize 2048 -validity 3650 -v -dname "CN = YWJ,OU = DevUI,O = DevCloud,L = ShenZhen,ST = GUANGDONG,C = CN"

2 CA机构的密钥库文件: ca.jks (CA密钥对都是模拟的)

keytool -genkey -alias ca -keystore ca.jks -keypass changeit -storepass changeit -keyalg RSA -keysize 2048 -validity 3650 -v -dname "CN = myca,OU = CA,O = CA,L = BEIJING,ST = BEIJING,C = CN"

接下来我们以DevUI这个组织机构为例,向CA机构申请签名证书

1)DevUI使用certreq生成一个证书签名请求文件devui_to_ca.csr

2)CA(证书认证中心)使用gencert生成证书ca_to_devui.cer

3)DevUI收到CA证书后,使用importcert将证书导入到自身的devui.jks

步骤1 DevUI使用certreq生成一个证书签名请求文件

DevUI使用自身的jks密钥生成一个证书签名请求

cmd命令:

keytool -certreq -alias devui -keystore devui.jks -file devui\_to\_ca.csr -v

参数说明:

-certreq 表示证书签名请求

-keystore <keystore> 密钥库名称

-alias <alias> 要处理的条目的别名

-file <filename> 输出文件名

-v 详细输出

这里创建的证书请求文件devui_to_ca.csr。将此文件提交到CA,例如VeriSign等。CA对请求者进行身份验证(通常是脱机),并返回由他们签名的证书,以对DevUI的公钥进行身份验证。

步骤2 CA(证书认证中心)使用gencert签发证书

Cmd命令:

keytool -gencert -alias ca -infile devui_to_ca.csr -outfile ca_to_devui.cer -keystore ca.jks

参数说明:

-alias <alias> 要处理的条目的别名

-keystore <keystore> 密钥库名称

-infile <filename> 输入文件名

-outfile <filename> 输出文件名

备注:这里模拟了CA(证书认证中心)根据csr文件生成证书的过程,真实情况下要向真实的CA例如VeriSign等,提交申请

步骤3 DevUI收到CA证书后,使用importcert将证书导入到自身的keystore中

Cmd命令:

keytool -importcert -file ca\_to\_devui.cer -keystore devui.jks -alias devui

这里出现错误,无法从回复中建立链:

keytool 错误: java.lang.Exception: 无法从回复中建立链

问题原因:ca.jks的证书时会对其签名做验证,需要确认是由信任机构CA颁发的。当前服务端当前并未将模拟CA的证书导入到的本机的信任证书列表中,导致抛出该错误

解决方案:首先从ca.jks导出CA机构的公钥证书ca.cer,然后将ca.cer导入devui.jks中。

1)从ca.jks导出CA机构的公钥证书ca.cer

Cmd命令:

keytool -exportcert -alias ca -file ca.cer -keystore ca.jks

2)将ca.cer导入devui.jks中

Cmd命令

keytool -importcert -alias ca -keystore devui.jks -file ca.cer -storepass changeit

默认密码也是changeit

3)通过证书查看命令可以看到包含两个证书的证书链

keytool -list -v -keystore devui.jks

步骤4 配置tomcat单向认证

<Connector
  protocol="org.apache.coyote.http11.Http11NioProtocol"
  port="443" maxThreads="200"
  scheme="https" secure="true" SSLEnabled="true"
  keystoreFile="keystore\_guanwang/devui.jks"
  keystorePass="changeit"
  clientAuth="false"
  sslProtocol="TLSv1.2"
/>

5 tomcat配置双向认证

Tomcat双向认证只需要在上面单向认证的基础上,增加如下步骤:

1 新增客户端认证文件client.jks

2 将ca_to_devui.cer导入到client.jks中

3 配置tomcat双向认证

步骤1 新增客户端认证文件

Cmd命令:

keytool -genkey -alias client -keystore client.jks -keypass changeit -storepass changeit -keyalg RSA -keysize 2048 -validity 3650 -v -dname "CN = client,OU = DevUIClient,O = DevCloud,L = ShenZhen,ST = GUANGDONG,C = CN"

步骤2 将ca.cer导入到client.jks中

Cmd命令

keytool -importcert -alias ca -keystore client.jks -file ca\_to\_devui.cer -storepass changeit

步骤3 配置tomcat双向认证

<Connector
  protocol="org.apache.coyote.http11.Http11NioProtocol"
  port="443"
  maxThreads="200"
  scheme="https"
  secure="true"
  SSLEnabled="true"
  keystoreFile="keystore\_guanwang/devui.jks"
  keystorePass="changeit"

  truststoreFile="keystore\_guanwang/client.jks"
  truststorePass="changeit"
  clientAuth="ture"

  sslProtocol="TLS"
/>

附录参考

https协议RFC:https://tools.ietf.org/html/rfc2818

维基百科:

HTTPS: https://zh.wikipedia.org/zh-cn/%E8%B6%85%E6%96%87%E6%9C%AC%E4%BC%A0%E8%BE%93%E5%AE%89%E5%85%A8%E5%8D%8F%E8%AE%AE

公开密钥加密(非对称加密):https://zh.wikipedia.org/wiki/%E5%85%AC%E5%BC%80%E5%AF%86%E9%92%A5%E5%8A%A0%E5%AF%86

数字签名:

https://zh.wikipedia.org/wiki/%E6%95%B8%E4%BD%8D%E7%B0%BD%E7%AB%A0

数字证书:

https://zh.wikipedia.org/zh-cn/%E5%85%AC%E9%96%8B%E9%87%91%E9%91%B0%E8%AA%8D%E8%AD%89

X.509证书:

https://zh.wikipedia.org/zh-cn/X.509

keytool官方说明:

https://docs.oracle.com/javase/8/docs/technotes/tools/windows/keytool.html

httpclient4.5 官方网站

https://hc.apache.org/httpcomponents-client-4.5.x/quickstart.html

httpclient客户端代码demo:

https://hc.apache.org/httpcomponents-client-4.5.x/httpclient/examples/org/apache/http/examples/client/ClientCustomSSL.java

https协议简要说明和数字签名可以参考如下文章:

https://zhuanlan.zhihu.com/p/57142784

https://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html

华为云证书申请流程

https://support.huaweicloud.com/qs-scm/scm_07_0001.html

参考书籍

《Java加密与解密的艺术》

《图解HTTP》

《图解密码技术》

加入我们

我们是DevUI团队,欢迎来这里和我们一起打造优雅高效的人机设计/研发体系。招聘邮箱:[email protected]

文/DevUI 杰哥

往期文章推荐

《关于Git rebase你必须要知道的几件事》

《Web界面深色模式和主题化开发》

《手把手教你搭建一个灰度发布环境》

03-05 21:24