断断续续接触过加密通讯的一些场景, 随着近两年安全的普及,建站使用https也成为标配.
混合加密机制(HTTPS)
结合了非对称加密和对称加密,公钥私钥主要用于传输对称加密的秘钥,真正的双方大数据量通讯都是通过对称加密进行。
先用非对称加密协商一个临时的对称加密密钥(会话密钥),然后双方再通过对称密钥对传递的大量数据进行加解密处理。
SSL规范:
- 预主密钥
- 主密钥
- PRF伪随机数函数算法
- 密钥协商算法ECDHE
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
流程如下:
客户端 | 服务端 | 通讯内容 |
---|---|---|
Client Hello | TLS版本,候选加密套件,候选压缩算法,随机数用于之后协商对称密钥 | |
Server Hello | 选择使用的协议版本、加密套件、压缩算法,及随机数 | |
Server Hello Done | 发送服务端证书 | |
验证证书:用本地CA公钥验证 | ||
Client Key Exchange | 之后产生随机数Pre-master,发送Client Key Exchange,用证书公钥加密 | |
Pre-master | 通过三个随机数:自己的、对方的和Pre-master,在客户端和服务端产生相同的对称密钥 | |
Change Cipher Spec | ||
Encrypted Handshake Message | 发送协商好的参数并用协商密钥加密,用于数据和握手验证 | |
Change Cipher Spec + Encrypted Handshake Message | ||
避免重放和篡改: 引入timestamp和nonce随机数。
SSL证书
有以下2个作用:
- 验证网站的唯一性 (保证访问者不是在一个伪造的站点)
- 加密传输的数据
互联网SSL证书
按信任等级由低到高为:
- 域名型SSL证书(DV SSL)/ Domain Validation: 等级普通,只验证域名所有权/网站的真实性
- 企业型SSL证书(OV SSL)/ Organization Validation: 等级高,需要验证企业身份和审核
- 增强型SSL证书(EV SSL)/ Extended Validation : 等级最高,一遍用于银行证券等金融机构,会显示为绿色网址栏
证书类型也可以分为:Single/Wildcard/Multi-Domain 三种类型.
SSL单向认证和SSL双向认证
- SSL单向认证只要求站点部署了ssl证书就行,任何用户都可以去访问(IP被限制除外等),只是服务端提供了身份认证。一般Web应用都是采用SSL单向认证的
- 双向认证则是需要服务端与客户端提供身份认证,只能是服务端允许的客户能去访问,安全性相对于要高一些。
通配符证书/Wild Card Certificates
在host包含来匹配多个子域名, 但只可以匹配一级子域名.
SAN/Subject Alternative Name也可以包含通配符主机名.
证书实战
mkcert
最简单的生成证书方式, 可用于开发测试环境
mkcert -install
mkcert example.com '*.example.org' 127.0.0.1
openssl使用
# Ubuntu生成自签名服务端证书和私钥
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /home/xulz/certs/server.key -out /home/xulz/certs/server.crt
# 生成证书和密钥到一个文件
openssl req -x509 -nodes -days 365 -new -keyout /home/xulz/certs/mail.pem -out /home/xulz/certs/mail.pem
#key和cert分开创建
openssl genrsa 2048 -out key.pem
openssl req -x509 -nodes -days 365 -new -key key.pem -out cert.pem
# 其他命令示例
# 产生私钥
openssl genrsa -aes256 4096 -out key.pem
# 产生不被密码保护的密钥
openssl genrsa 4096 -out key.pem
# 使用新版genpkey命令
openssl genpkey -algorithm RSA -out key.pem -aes-256-cbc -pkeyopt rsa_keygen_bits:4096
# 改用更强算法加密
openssl pkcs12 -in weak.p12 -nodes -out decrypted.pem
openssl pkcs12 -export -in decrypted.pem -keypbe AES-128-CBC -certpbe AES-128-CBC -out strong.p12
# 测试SSL server
openssl s_client -connect ssl.xulizhao.com:443
openssl req命令行参数
- -new new request.
- -out arg output file
- -nodes don’t encrypt the output key
- -x509 output a x509 structure instead of a cert. req.
- -days number of days a certificate generated by -x509 is valid for.
- -keyout arg file to send the key to
- -key file use the private key contained in file
openssl genpkey [-out filename] [-outform PEM|DER] [-pass arg] [-cipher] [-engine id] [-paramfile file] [-algorithm alg] [-pkeyopt opt:value] [-genparam] [-text]
openssl genrsa [-out filename] [-passout arg] [-des] [-des3] [-idea] [-f4] [-3] [-rand file(s)] [-engine id] [numbits]
keytool
Linux/Mac中OpenSSL的证书和密钥管理工具
# 产生密钥对
keytool -genkeypair -alias test123 -keystore test123.pfx -storepass test123 -validity 365 - keyalg RSA -keysize 2048 -storetype pkcs12
# java证书管理
# 列出证书信息和别名
keytool -list -v -keystore cacerts
# 证书导入
keytool -import -alias foo -file certfile.cer -keystore publicKey.store
# 把其他jks导入已有jks,比如cacerts
keytool -importkeystore -srckeystore source.jks -destkeystore dest.jks
目录服务
开源服务:
keytool -genkey -keyalg "RSA" -dname "cn=zanzibar, ou=ApacheDS, o=ASF, c=US" -alias zanzibar -keystore zanzibar.ks -storepass secret -validity 730
docker cp zanzibar.ks demo:/usr/local/java/jre/lib/security/
docker exec -ti demo bash
cd /usr/local/java/jre/lib/security/
../../bin/keytool -importkeystore -srckeystore zanzibar.ks -destkeystore cacerts # changeit
Misc
工具
- testssl.sh: 强大友好的SSL证书测试命令行工具
- certbot / Nginx on Ubuntu 20.04
- mkcert
- Windows证书管理: certmgr.msc
- Stunnel: 代理服务,在C/S间增加TLS