SSL证书实践

概要

现在web系统基本上时HTTPS,并且连接安全的,才会被用户认为是可安全访问的。
下面介绍一种免费证书的导入方式。

整体架构流程

  1. 证书生成
  2. 证书验证
  3. 定期更新有效期

技术名词解释

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)
建立安全连接的过程,包括协商加密算法、交换密钥、验证证书等步骤。

工作原理

  1. 客户端向服务器发起HTTPS请求。
  2. 服务器返回SSL证书和公钥。
  3. 客户端验证证书有效性(如域名匹配、CA可信)。
  4. 双方协商生成会话密钥,用于对称加密后续通信。

示例代码(验证证书的Python片段)

import requests
response = requests.get("https://example.com", verify=True)  # 启用证书验证
print(response.status_code)

数学公式(密钥交换简化模型)

客户端生成随机数a,服务器生成随机数b,通过迪菲-赫尔曼算法计算共享密钥:
\( K = g^{ab} \mod p \)
其中g为生成元,p为大质数。

技术细节


证书生成

  1. 通过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个月有效期。
    点开
    证书安全

定期更新有效期

  • 上步可以看到,证书是免费,需要脚本定期更新
    下面写一下基本思路
Y
N
p12证书是否超过3个月
启动nginx
结束
执行脚本生成证书
拷贝证书到指定目录
重启tomcat
停止nginx
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑞瑞绮绮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值