目录:
数字证书电子证书,类似于日常生活中的身份证,也是另外一种形式的身份认证,用于标识网络中的用于身份。
数字证书集合了多种密码学的加密算法,证书自身带有公钥信息,可以完成相应的加密、解密操作。同时,还拥有自身信息的数字签名,可以鉴别证书的颁发机构,以及证书内容的完整性。
https协议
HTTPS 能够加密信息,以免敏感信息被第三方获取,所以很多银行网站或电子邮箱等等安全级别较高的服务都会采用HTTPS协议。
HTTPS协议位于应用层和网络层之间,它其实由两部分组成:HTTP + SSL / TLS,也就是在HTTP上又加了一层处理加密信息的模块。服务端和客户端的信息传输都会通过TLS进行加密,所以传输的数据都是加密后的数据。
一般在个人访问网站时,为了保证安全性,很多网站提供了安全证书。网站服务器端提供证书,该证书中包含了一个RSA公钥。浏览器,也就是客户端通过该证书进行安全性验证,如果该证书是值得信任的,就通过该证书中的公钥来对一个对称加密密钥进行加密。服务器端则通过RSA私钥进行解密,得到客户端传输过来的对称密钥。这个对称密钥是用来对双方在传输过程中的信息进行加密的。由于只能通过RSA私钥对这个加密过的对称密钥进行解密,所以就算双方传输的信息被中途截获,也无法破解密钥从而对传输的信息进行解密(这里要求对对称机密机制和非对称加密机制有一定了解),从而保证了数据传输的安全性。
https 访问后端服务
下面用一个简单的demo来演示如何配置 https 访问 tomcat 服务器。
配置tomcat使用https协议访问其实很简单,主要有以下步骤。
生成服务器的证书
通过以下命令来生成服务器端的证书并设置以下内容:
keytool -genkey -alias tomcat -keyalg RSA -keystore /tmp/server_test.keystore
Enter keystore password:
Keystore password is too short - must be at least 6 characters
Enter keystore password:
Re-enter new password:
What is your first and last name?
[Unknown]: test
What is the name of your organizational unit?
[Unknown]: test
What is the name of your organization?
[Unknown]: test
What is the name of your City or Locality?
[Unknown]: CN
What is the name of your State or Province?
[Unknown]: JS
What is the two-letter country code for this unit?
[Unknown]: CN
Is CN=test, OU=test, O=test, L=CN, ST=JS, C=CN correct?
[no]: yes
Generating 2,048 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 90 days
for: CN=test, OU=test, O=test, L=CN, ST=JS, C=CN
密钥库口令自己设置,默认是changeit。完成之后在相应目录下生成服务器证书。
注意:提示输入名字和姓氏的时候其实就是服务域名,不能为 IP 地址。
导出服务器证书
生成的证书需要进一步导出为cer:
keytool -export -alias tomcat –keystore /tmp/server_test.keystore -file /tmp/server_test.cer
第一个路径是生成的证书的路径,第二个路径是导出之后的证书路径。完成之后会相应目录下生成证书文件。
安装证书
双击安装证书到浏览器,选择自动选择证书颁发机构类型。
正常情况下,证书不是随便颁发的。证书的颁发机构必须是授信机构,而这里是我自己颁发的,也就是第一步生成证书时输入的相关内容:
Is CN=test, OU=test, O=test, L=CN, ST=JS, C=CN
所以只能自己测试用。
修改服务器配置
这里使用tomcat作为服务器,修改server.xml文件:
注意这里只是演示,证书库和密码根据自己的设置来
clientAuth默认为false,表示客户端单方面需要验证服务器端证书。在上面的步骤中也只单方面提供了服务器证书。
访问域名
访问时需按照之前输入的域名来访问,所以还需要在host文件中添加一行:127.0.0.1
启动tomcat服务器,通过https://{域名}:8443来访问服务器。会发现现在的链接是https的了。
访问 Springboot 服务
重新生成一个服务端证书:
keytool -genkey -alias myserver -keyalg RSA -keystore /tmp/keystore.p12 -storepass changeit
将生成的证书拷贝到 springboot 项目的 rerouces 目录下。
在 application.properties 中开启https访问:
server.port=8443
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=changeit
server.ssl.key-store-type=PKCS12
修改本地 dns 解析,将证书的域名指向本地。证书域名即生成时输入的用户名,如果忘记了,可以用 keystore explorer 之类的工具,或者直接用 openssl 打开即可查看:
openssl x509 -in /tmp/keystore.p12 -noout -text
假设证书域名为 test.com, springboot 项目路径为 /hello,用 https://test.com/hello 即可访问。
同样的,访问时会提示证书不安全,因为该证书是自己颁发的,不在系统信任列表内。
可信列表和mTLS
上文的测试demo中自己颁发的证书是不受信任的,所以不管是浏览器还是curl,都会提示不安全。
当你访问https时,服务端会把服务端证书发给客户端(浏览器、curl),这个证书里包含:公钥(用于加密、验证签名),域名信息(证书只对这些域名生效),签发者(Issuer),有效期。
但客户端是否信任这个证书,是由CA列表决定的。客户端系统都会维护一个受信任的CA列表。Windows/macOS有系统的根证书,Linux curl 用的是 /etc/ssl/certs/ca-certificates.crt,Java 用的是 cacerts($JAVA_HOME/lib/security/cacerts)。
CA 列表中都是根证书,相当于白名单。只要某个证书最终能追溯到这其中任意根证书,客户端就认为是可信的。举个例子,假设服务端证书是某个中间CA颁发的,这个中间CA是由一个根CA颁发的,而这个根CA刚好在CA列表中,则这个服务端证书是可信任的。
mTLS
服务器出示证书,客户端验证证书。这是单向验证,即普通 TLS。
在对安全比较严格的场合,除了客户端验证服务端证书之外,服务端也会验证客户端证书,这叫双向 TLS(mTLS)。
在双向认证时,通常有两种做法:
- 自建CA,用自建CA来签发客户端证书,服务端信任自建CA。
- 客户端自己签发证书,服务端直接信任客户端证书。
无论是信任CA还是信任单个客户端证书,都要把信任的证书导入到 truststore。服务端配置如下:
server:
ssl:
enabled: true
key-store: classpath:server-keystore.p12
key-store-password: changeit
key-store-type: PKCS12
trust-store: classpath:truststore.p12
trust-store-password: changeit
trust-store-type: PKCS12
client-auth: need
trust-store 里放自签名的中间 CA 证书或客户端证书本身。
假设现在有一个客户端证书由中间CA签发,而中间CA由根CA签发,根CA是自签名的。现在需要准备三份证书:
- 根CA(自签名):root-ca.crt
- 中间CA: intermediate-ca.crt
- 客户端证书:client.crt
这是典型的三层证书链,只需要将中间CA和根CA放到trust-store即可。可以直接复制粘贴,也可以用命令行导入。
命令行导入:
keytool -importcert -file root-ca.crt -alias root-ca -keystore truststore.p12 -storetype PKCS12 -storepass changeit -noprompt
keytool -importcert -file intermediate-ca.crt -alias intermediate-ca -keystore truststore.p12 -storetype PKCS12 -storepass changeit -noprompt
中间CA可以导入,也可以不导入,如果客户端证书里已经包含完整链,Java 会自动找到中间CA。
也可以直接将中间CA和根CA放到同一个crt,然后导入到 truststore.p12。对于 truststore (保存可信CA)来说,证书链的顺序是无所谓的,推荐从低到高的顺序。
注意如果是keystore,则必须要保持从低到高的顺序,即: 自己证书 -> 中间证书 -> 根证书。
可以通过命令来验证客户端证书是否可信:
openssl verify -CAfile ca.crt client.crt
在开启 mTLS 的情况下,验证请求是否正常:
curl -v https://test.com/hello --cert client.crt --key client.key --cacert ca.crt
1万+

被折叠的 条评论
为什么被折叠?



