数字证书与https协议

目录:

  1. 数字证书与https协议
  2. https协议介绍

数字证书电子证书,类似于日常生活中的身份证,也是另外一种形式的身份认证,用于标识网络中的用于身份。

数字证书集合了多种密码学的加密算法,证书自身带有公钥信息,可以完成相应的加密、解密操作。同时,还拥有自身信息的数字签名,可以鉴别证书的颁发机构,以及证书内容的完整性。

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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值