文章目录
概要
现在web系统基本上时HTTPS,并且连接安全的,才会被用户认为是可安全访问的。
下面介绍一种免费证书的导入方式。
整体架构流程
- 证书生成
- 证书验证
- 定期更新有效期
技术名词解释
SSL(Secure Sockets Layer)
SSL是一种加密协议,用于在互联网上建立安全的通信通道。它通过加密数据传输(如登录凭证、支付信息等)防止第三方窃取或篡改数据。SSL现已被更先进的TLS(Transport Layer Security)协议取代,但“SSL”仍被广泛用作通用术语。
HTTPS(HyperText Transfer Protocol Secure)
HTTPS是HTTP的安全版本,通过SSL/TLS协议对数据进行加密传输。它在HTTP基础上增加了身份验证和数据完整性保护,确保用户与网站间的通信不被监听或伪造。HTTPS的URL以https://开头,浏览器通常会显示锁形图标标识安全性。
关键组件
证书(Certificate)
由受信任的证书颁发机构(CA)签发,用于验证网站身份。包含域名、公钥、有效期等信息。
公钥/私钥(Public/Private Key)
非对称加密的核心。公钥用于加密数据,私钥用于解密,确保只有目标服务器能读取信息。
握手协议(Handshake)
建立安全连接的过程,包括协商加密算法、交换密钥、验证证书等步骤。
工作原理
- 客户端向服务器发起HTTPS请求。
- 服务器返回SSL证书和公钥。
- 客户端验证证书有效性(如域名匹配、CA可信)。
- 双方协商生成会话密钥,用于对称加密后续通信。
示例代码(验证证书的Python片段)
import requests
response = requests.get("https://example.com", verify=True) # 启用证书验证
print(response.status_code)
数学公式(密钥交换简化模型)
客户端生成随机数a,服务器生成随机数b,通过迪菲-赫尔曼算法计算共享密钥:
\( K = g^{ab} \mod p \)
其中g为生成元,p为大质数。
技术细节
证书生成
- 通过let encry生成的证书,转成tomcat证书
- 从https://github.com/xdtianyu/scripts/blob/master/lets-encrypt/README-CN.md 下载letsencrypt.sh 和letsencrypt.conf
- letsencrypt.sh内容如下
#!/bin/bash
# Usage: /etc/nginx/certs/letsencrypt.sh /etc/nginx/certs/letsencrypt.conf
CONFIG=$1
ACME_TINY="/tmp/acme_tiny.py"
DOMAIN_KEY=""
if [ -f "$CONFIG" ];then
. "$CONFIG"
DIRNAME=$(dirname "$CONFIG")
cd "$DIRNAME" || exit 1
else
echo "ERROR CONFIG."
exit 1
fi
KEY_PREFIX="${DOMAIN_KEY%%.*}"
DOMAIN_CRT="$KEY_PREFIX.crt"
DOMAIN_PEM="$KEY_PREFIX.pem"
DOMAIN_CSR="$KEY_PREFIX.csr"
DOMAIN_CHAINED_CRT="$KEY_PREFIX.chained.crt"
if [ ! -f "$ACCOUNT_KEY" ];then
echo "Generate account key..."
openssl genrsa 4096 > "$ACCOUNT_KEY"
fi
if [ ! -f "$DOMAIN_KEY" ];then
echo "Generate domain key..."
if [ "$ECC" = "TRUE" ];then
openssl ecparam -genkey -name secp256r1 | openssl ec -out "$DOMAIN_KEY"
else
openssl genrsa 2048 > "$DOMAIN_KEY"
fi
fi
echo "Generate CSR...$DOMAIN_CSR"
OPENSSL_CONF="/etc/ssl/openssl.cnf"
if [ ! -f "$OPENSSL_CONF" ];then
OPENSSL_CONF="/etc/pki/tls/openssl.cnf"
if [ ! -f "$OPENSSL_CONF" ];then
echo "Error, file openssl.cnf not found."
exit 1
fi
fi
openssl req -new -sha256 -key "$DOMAIN_KEY" -subj "/" -reqexts SAN -config <(cat $OPENSSL_CONF <(printf "[SAN]\nsubjectAltName=%s" "$DOMAINS")) > "$DOMAIN_CSR"
wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py --no-check-certificate -O $ACME_TINY -o /dev/null
if [ -f "$DOMAIN_CRT" ];then
mv "$DOMAIN_CRT" "$DOMAIN_CRT-OLD-$(date +%y%m%d-%H%M%S)"
fi
DOMAIN_DIR="$DOMAIN_DIR/.well-known/acme-challenge/"
mkdir -p "$DOMAIN_DIR"
python $ACME_TINY --account-key "$ACCOUNT_KEY" --csr "$DOMAIN_CSR" --acme-dir "$DOMAIN_DIR" > "$DOMAIN_CRT"
if [ "$?" != 0 ];then
exit 1
fi
if [ ! -f "lets-encrypt-x3-cross-signed.pem" ];then
wget https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem --no-check-certificate -o /dev/null
fi
cat "$DOMAIN_CRT" lets-encrypt-x3-cross-signed.pem > "$DOMAIN_CHAINED_CRT"
if [ "$LIGHTTPD" = "TRUE" ];then
cat "$DOMAIN_KEY" "$DOMAIN_CRT" > "$DOMAIN_PEM"
echo -e "\e[01;32mNew pem: $DOMAIN_PEM has been generated\e[0m"
fi
echo -e "\e[01;32mNew cert: $DOMAIN_CHAINED_CRT has been generated\e[0m"
#service nginx reload
- letsencrypt.conf 内容如下
# only modify the values, key files will be generated automaticly.
ACCOUNT_KEY="letsencrypt-account.key"
DOMAIN_KEY="你的域名.key"
DOMAIN_DIR="/usr/local/nginx/html"
DOMAINS="DNS:你的域名"
#ECC=TRUE
#LIGHTTPD=TRUE
- 先安装一个nginx,并映射端口80,同时配置nginx.conf文件 这步很关键,下面脚本执行会通过域名+80端口+文件路径访问一个文件确定域名有效性,才会生成证书。
nginx.conf修改部分
server {
listen 80;
server_name localhost;
# 这里可能不需要配置
ssl_certificate /ssl/域名第一个词.chained.crt;
ssl_certificate_key /ssl/域名.key;
location / {
root html;
index index.html index.htm;
}
#一键申请SSL证书验证目录相关设置
location ~ \.well-known{
allow all;
}
}
- 执行如下脚本,生成key,如果不成功,查看日志/var/log/lets-encrypt.log分析
letsencrypt.sh letsencrypt.conf >> /var/log/lets-encrypt.log 2>&1
- 执行后生成一堆文件
-rw-r--r--. 1 root root 5254 Sep 12 09:31 域名第一个词.chained.crt
-rw-r--r--. 1 root root 3607 Sep 12 09:31 域名第一个词.crt
-rw-r--r--. 1 root root 936 Sep 12 09:31 域名第一个词.csr
-rw-r--r--. 1 root root 1679 Mar 21 15:49 域名.key
-rw-r--r--. 1 root root 3243 Mar 21 15:49 letsencrypt-account.key
-rw-r--r--. 1 root root 242 Mar 21 16:02 letsencrypt.conf
-rwxr-xr-x. 1 root root 2170 Mar 21 15:45 letsencrypt.sh
-rw-r--r--. 1 root root 1647 Mar 21 16:03 lets-encrypt-x3-cross-signed.pem
- 我用的是tomcat9,需要把证书转为p12格式,password.txt里面是密码,tomcat9配置文件会用到
openssl pkcs12 -export -inkey 你的域名.key -in 域名第一个词.chained.crt -out tomcat9_keystore.p12 -name tomcat9_ssl -caname root -passout file:./password.txt
- 拷贝tomcat9_keystore.p12到tomcat9安装目录下,比如tomcat/conf
- 编辑server.xml,配置文件路径和密码
<!-- 找到8443 或者 443 位置 -->
<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
maxThreads="150" SSLEnabled="true">
<SSLHostConfig>
<Certificate certificateKeystoreFile="tomcat/conf/tomcat9_keystore.p12"
certificateKeystorePassword="12345678"
certificateKeystoreType="PKCS12"
type="RSA" />
</SSLHostConfig>
</Connector>
证书验证
- 启动tomcat,注意控制台,看是否有加载ssl正确的info记录
29-Jul-2025 08:16:49.488 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["https-jsse-nio-8443"]
29-Jul-2025 08:16:49.778 INFO [main] org.apache.tomcat.util.net.AbstractEndpoint.logCertificate Connector [https-jsse-nio-8443], TLS virtual host [_default_], certificate type [RSA] configured from keystore [tomcat/conf/tomcat9_keystore.p12] using alias [tomcat] with trust store [null]
- 若无问题,说明配置正确,访问域名,点开会看到链接是安全的,并且3个月有效期。


定期更新有效期
- 上步可以看到,证书是免费,需要脚本定期更新
下面写一下基本思路

811

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



