加密与证书体系知识总结

涵盖:对称加密、非对称加密、数字签名、数字证书、证书信任链、中间人攻击、HTTPS/TLS 混合加密,以及内网 Harbor 自签证书实例。


一、对称加密(Symmetric Encryption)

原理

加密和解密使用同一把密钥。通信双方必须预先安全地共享该密钥。

常见算法

算法说明
AES(AES-128/256-GCM)当前主流标准,安全高效
ChaCha20-Poly1305移动端/无硬件加速场景常用
SM4国密算法
3DES、DES已淘汰或不推荐

优缺点

  • ✅ 速度快、效率高,适合加密大量数据
  • ❌ 密钥分发困难:如何把密钥安全送给对方本身就是难题
  • ❌ 密钥管理成本高:N 人两两通信需要 N(N−1)/2 个密钥
  • ❌ 无法认证身份:无法确认消息发送方是谁,也无法发现篡改

二、非对称加密(Asymmetric Encryption)

原理

使用算法生成密钥对:公钥(Public Key)+ 私钥(Private Key)。

  • 公钥:可公开给任何人,用于加密或验签
  • 私钥:必须自己保管,用于解密或签名

经典口诀:公钥加密私钥解(保密),私钥签名公钥验(认证)。

注意:「私钥加密」并非真正的保密手段——因为公钥公开,任何人都能解。私钥操作的真正用途是数字签名,用于证明身份。

常见算法

算法说明
RSA(2048/4096 位)最经典,加解密、签名均可
ECC(ECDSA/Ed25519)密钥更短、性能更好,现代主流
SM2国密非对称算法

优缺点

  • ✅ 私钥不传播,天然解决密钥分发问题
  • ✅ 结合数字签名可实现身份认证和完整性校验
  • ✅ 管理方便:每人只需一对密钥
  • ❌ 计算慢,不适合加密大数据量
  • ❌ 单纯的公钥交换会遭受中间人攻击(见第六节)

三、数字签名(Digital Signature)

为什么需要

非对称加密解决了「保密」,但还需要证明「这条消息确实来自声称的发送方,且未被篡改」。

原理

发送方:消息 → 哈希运算(SHA-256/SHA-512)→ 摘要 → 用私钥加密摘要 → 数字签名
接收方:消息 → 哈希运算 → 新摘要
        用公钥解密签名 → 旧摘要
        两个摘要一致 → 消息完整且来源可信

提供的能力

能力说明
身份认证只有私钥持有者能生成有效签名
完整性消息被篡改则哈希值不匹配
不可否认性签名者事后无法否认签过名

注意:哈希(如 SHA-256)是单向摘要算法,不属于加密。


四、数字证书(Digital Certificate)

解决什么问题

数字签名仍需确认「这把公钥真的属于对方吗?」——证书将身份与公钥绑定,由可信第三方(CA)担保。

证书内容(X.509 标准)

- 持有者身份信息(域名、组织、国家等)
- 持有者的公钥
- 签发者(CA)信息
- 有效期
- 扩展信息:密钥用途、SAN(主题备用名称,即证书适用的域名/IP)
- CA 对以上全部内容的数字签名

申请流程

1. 服务器生成密钥对(私钥 + 公钥)
2. 向 CA 提交 CSR(证书签名请求):公钥 + 身份信息
3. CA 审核后,用自己的私钥对 CSR 内容签名,签发证书

关键字段:SAN(Subject Alternative Name)

现代浏览器只认 SAN 不认 CN。证书中的 DNS.1=www.example.com 必须与访问地址完全一致,否则报证书错误。


五、证书信任链(Chain of Trust)

结构

根 CA(Root CA)                ← 证书颁发机构/自签证书,预装在操作系统/浏览器信任库
  └── 中间 CA(Intermediate CA)← 由根 CA 签发
        └── 服务器证书          ← 由中间 CA 签发

为什么需要中间 CA

  1. 隔离风险:中间 CA 私钥泄露,可用根 CA 撤销它,不殃及全局
  2. 减少根 CA 使用频率:根私钥离线保管,更安全
  3. 分层管理:不同业务线使用不同中间 CA

客户端验证流程

1. 收到服务器证书 + 中间 CA 证书(证书链)
2. 用中间 CA 公钥验证服务器证书签名 ✓
3. 用根 CA 公钥(系统预装)验证中间 CA 签名 ✓
4. 检查服务器证书:域名(SAN)匹配?在有效期内?密钥用途正确?
5. 检查吊销状态(CRL / OCSP)
6. 全部通过 → 信任该证书中的公钥

自签证书

  • 自己扮演 CA:生成 CA 密钥对,自签 CA 证书,再用它签发服务器证书
  • 缺点:浏览器/系统默认不信任,必须手动把自签 CA 证书导入信任库
  • 适用场景:内网、测试环境(如内网 Harbor、Kubernetes)

六、中间人攻击(MITM)与防御

攻击方式

A ←—— 攻击者 ——→ B
  A 请求 B 的公钥,攻击者截获并换成自己的公钥
  → A 用「假公钥」加密 → 攻击者用自己的私钥解开 → 再转发给 B
  → A、B 都毫无察觉,通信全程被窃听和篡改

常见手段:钓鱼 WiFi、DNS 劫持、ARP 欺骗。

防御核心

攻击者无法伪造 CA 签名(不知道 CA 私钥),所以只要客户端严格校验证书链,替换证书就会立刻暴露。防御要点:

  • 始终验证证书链和域名
  • 不信任来源不明的 CA
  • 使用 HSTS 强制 HTTPS

七、混合加密:HTTPS/TLS 的真实工作方式

对称加密快但没有安全分发渠道;非对称加密安全但慢。实际系统二者结合:

1. 客户端连接服务器,获取数字证书
2. 客户端验证证书(信任链 → 域名 → 有效期)
3. 客户端生成随机的「会话密钥」(对称密钥),
   用证书中的服务器公钥加密后发送(非对称加密)
4. 服务器用私钥解出会话密钥
5. 后续所有数据用会话密钥做对称加密传输(快)

一句话:非对称加密负责「认证身份 + 安全交换会话密钥」,对称加密负责「高效传输数据」。现代 TLS 还使用临时 ECDHE 密钥交换提供前向保密(PFS)——即使私钥日后泄露,历史会话也无法被解密。


八、实例:内网 Harbor 自签证书对应关系

文件对应概念
ca.keyCA 私钥,用于给证书签名,最需保密
ca.crt根 CA 自签证书,需分发到客户端信任库
www.harbor.com.key服务器私钥,用于解密会话密钥
www.harbor.com.csr证书申请文件(公钥 + 身份信息)
www.harbor.com.crt数字证书 = 身份信息 + 公钥 + CA 数字签名
san.ext 中 SAN客户端验证域名时检查的目标

完整链路:ca.key 签名 → 生成 www.harbor.com.crt → 客户端导入 ca.crt 建立信任 → 验签通过 → 公钥交换会话密钥 → 对称加密传输数据。任何一环证书不匹配或 CA 不被信任,HTTPS 连接就会失败。


九、添加自建CA到系统信任库

Windows

使用管理员打开Powershell命令行终端,进入ca证书存放目录,执行以下命令
certutil -addstore -f Root ca.crt

image-iHaG.png
另一种方式是双击 ca.crt ,点击“安装证书”,存储位置选择“本地计算机”,然后向导会要求选择证书存储,手动选择“受信任的根证书颁发机构”,一路确认即可。

image-wKwk.png

Linux(Debian/Ubuntu)

cp ca.crt /usr/local/share/ca-certificates/ca.crt
update-ca-certificates

Linux(CentOS/RHEL)

cp ca.crt /etc/pki/ca-trust/source/anchors/
update-ca-trust

十、自建CA及服务器证书脚本(OpenSSL)

#!/usr/bin/env bash
set -euo pipefail

WORK_DIR=/home/certs
DOMAIN_NAME=www.harbor.com
IP=192.168.2.6

umask 077

log_msg() {
    local level="$1"
    local msg="$2"
    local timestamp
    timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo "[${timestamp}] [${level}] ${msg}"
}

usage() {
    cat <<EOF
用法: $0 <选项> [参数]

功能选项:
    1   创建新的 CA + 服务器证书(全新生成)
    2   基于已存在的 CA 创建服务器证书

用法示例:
    $0 1                                # 新建 CA + 服务器证书(域名/IP 使用脚本默认值)
    $0 1 www.example.com 192.168.1.10   # 新建 CA + 服务器证书(指定域名/IP)
    $0 2 www.example.com 192.168.1.10 /path/to/ca.crt /path/to/ca.key
                                      # 基于已有 CA 创建服务器证书(需指定 CA 证书和私钥路径)
EOF
    exit 1
}

# ---------- 参数解析 ----------
[ $# -ge 1 ] || usage
MODE="$1"
[ "$MODE" = "1" ] || [ "$MODE" = "2" ] || { log_msg "ERROR" "无效选项: $MODE(仅支持 1 或 2)"; usage; }

# 域名/IP:优先使用命令行参数,否则使用默认值
[ $# -ge 2 ] && DOMAIN_NAME="$2"
[ $# -ge 3 ] && IP="$3"

if [ "$MODE" = "2" ]; then
    [ $# -ge 4 ] || { log_msg "ERROR" "选项2需要指定 CA 证书路径和 CA 私钥路径"; usage; }
    CA_CERT_PATH="$4"
    CA_KEY_PATH="$5"
    for f in "$CA_CERT_PATH" "$CA_KEY_PATH"; do
        [ -f "$f" ] || { log_msg "ERROR" "文件不存在: $f"; exit 1; }
    done
fi

SAVE_DIR="$WORK_DIR/$(date '+%Y%m%d%H%M%S')"
install -d "$SAVE_DIR"
cd "$SAVE_DIR"

# 选项1时,CA 证书/私钥放在本次输出目录
[ "$MODE" = "1" ] && { CA_KEY_PATH="$SAVE_DIR/ca.key"; CA_CERT_PATH="$SAVE_DIR/ca.crt"; }

SERVER_KEY_PATH="$SAVE_DIR/$DOMAIN_NAME.key"
SERVER_CSR_PATH="$SAVE_DIR/$DOMAIN_NAME.csr"
SERVER_CERT_PATH="$SAVE_DIR/$DOMAIN_NAME.crt"
V3_EXT="$SAVE_DIR/v3.ext"

# ---------- 生成 CA(仅选项1) ----------
create_ca() {
    log_msg "INFO" "正在生成CA私钥"
    openssl genrsa -out "$CA_KEY_PATH" 4096

    log_msg "INFO" "正在生成CA证书"
    openssl req -x509 -new -nodes -sha512 -days 36500 \
      -subj "/C=CN/ST=GuangDong/L=Guangzhou/O=Personal/OU=Personal/CN=Root CA" \
      -key "$CA_KEY_PATH" \
      -out "$CA_CERT_PATH" \
      -addext "basicConstraints=critical,CA:TRUE" \
      -addext "keyUsage=critical,keyCertSign,cRLSign"
}

# ---------- 生成服务器证书 ----------
create_server_cert() {
    log_msg "INFO" "正在生成服务器私钥"
    openssl genrsa -out "$SERVER_KEY_PATH" 4096

    log_msg "INFO" "正在生成服务器证书请求"
    openssl req -sha512 -new \
      -subj "/C=CN/ST=GuangDong/L=Guangzhou/O=Personal/OU=Personal/CN=$DOMAIN_NAME" \
      -key "$SERVER_KEY_PATH" \
      -out "$SERVER_CSR_PATH"

    cat > "$V3_EXT" <<EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth
subjectAltName=@alt_names

[alt_names]
DNS.1=$DOMAIN_NAME
IP.1=$IP
EOF

    log_msg "INFO" "正在生成服务器证书"
    openssl x509 -req -sha512 -days 365 \
      -in "$SERVER_CSR_PATH" \
      -CA "$CA_CERT_PATH" -CAkey "$CA_KEY_PATH" \
      -CAserial "$SAVE_DIR/ca.srl" -CAcreateserial \
      -extfile "$V3_EXT" \
      -out "$SERVER_CERT_PATH"

    rm -f "$V3_EXT"
    chmod 600 "$CA_KEY_PATH" "$SERVER_KEY_PATH" 2>/dev/null || true
}

# ---------- 主流程 ----------
case "$MODE" in
    1)
        log_msg "INFO" "模式1:创建新的 CA + 服务器证书"
        create_ca
        create_server_cert
        ;;
    2)
        log_msg "INFO" "模式2:基于已有 CA 创建服务器证书"
        create_server_cert
        ;;
esac

log_msg "INFO" "CA cert:     $CA_CERT_PATH"
log_msg "INFO" "Server cert: $SERVER_CERT_PATH"
log_msg "INFO" "Server key:  $SERVER_KEY_PATH"
log_msg "INFO" "=================证书信息================"
log_msg "INFO" "$(openssl verify -CAfile "$CA_CERT_PATH" "$SERVER_CERT_PATH")"
log_msg "INFO" "$(openssl x509 -in "$SERVER_CERT_PATH" -noout -text | grep -EA1 'Subject Alternative Name|Not Before')"