### 一、安装CFSSL工具 CFSSL(CloudFlare's PKI Toolkit)是一个开源的PKI工具集,可用于创建私有CA和证书。 1. **Linux/macOS**: ```bash # 下载cfssl和cfssljson工具 curl -o cfssl https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 curl -o cfssljson https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 chmod +x cfssl cfssljson sudo mv cfssl cfssljson /usr/local/bin/ ``` 2. **Windows**: - 从 [CFSSL Releases](https://github.com/cloudflare/cfssl/releases) 下载对应版本的 `cfssl.exe` 和 `cfssljson.exe` - 将可执行文件添加到系统PATH路径 ### 二、创建私有CA #### 1. 配置CA证书 创建一个名为 `ca-config.json` 的文件,定义证书的有效期和使用策略: ```json { "signing": { "default": { "expiry": "87600h" // 10年有效期 }, "profiles": { "server": { "expiry": "87600h", "usages": ["signing", "key encipherment", "server auth"] }, "client": { "expiry": "87600h", "usages": ["signing", "key encipherment", "client auth"] }, "peer": { "expiry": "87600h", "usages": ["signing", "key encipherment", "server auth", "client auth"] } } } } ``` #### 2. 创建CA证书签名请求(CSR)配置 创建 `ca-csr.json` 文件: ```json { "CN": "My Private CA", "key": { "algo": "rsa", "size": 4096 }, "names": [ { "C": "CN", "ST": "Shanghai", "L": "Shanghai", "O": "My Organization", "OU": "IT Department" } ], "ca": { "expiry": "87600h" // CA证书有效期10年 } } ``` #### 3. 生成CA证书和私钥 执行以下命令生成自签名CA证书: ```bash cfssl gencert -initca ca-csr.json | cfssljson -bare ca ``` 这将生成三个文件: - `ca.pem`:CA公钥证书 - `ca-key.pem`:CA私钥(妥善保管,不要泄露) - `ca.csr`:CA证书签名请求 ### 三、使用CA签署服务器证书 #### 1. 创建服务器证书CSR配置 创建 `server-csr.json` 文件: ```json { "CN": "server.example.com", "hosts": [ "server.example.com", "192.168.1.100", "localhost", "127.0.0.1" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "Shanghai", "L": "Shanghai", "O": "My Organization", "OU": "IT Department" } ] } ``` > 注意:`hosts` 字段必须包含服务器的域名、IP地址以及任何需要访问的别名 #### 2. 生成服务器证书和私钥 使用CA直接签署服务器证书: ```bash cfssl gencert \ -ca=ca.pem \ -ca-key=ca-key.pem \ -config=ca-config.json \ -profile=server \ server-csr.json | cfssljson -bare server ``` 这将生成: - `server.pem`:服务器公钥证书 - `server-key.pem`:服务器私钥 ### 四、使用CA签署客户端证书 #### 1. 创建客户端证书CSR配置 创建 `client-csr.json` 文件: ```json { "CN": "client.example.com", "hosts": [], // 客户端证书通常不需要指定hosts "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "ST": "Shanghai", "L": "Shanghai", "O": "My Organization", "OU": "IT Department" } ] } ``` #### 2. 生成客户端证书和私钥 ```bash cfssl gencert \ -ca=ca.pem \ -ca-key=ca-key.pem \ -config=ca-config.json \ -profile=client \ client-csr.json | cfssljson -bare client ``` 这将生成: - `client.pem`:客户端公钥证书 - `client-key.pem`:客户端私钥 ### 五、证书验证 #### 1. 验证服务器证书 ```bash openssl verify -CAfile ca.pem server.pem ``` 如果输出 `server.pem: OK`,则证书有效 #### 2. 验证客户端证书 ```bash openssl verify -CAfile ca.pem client.pem ``` ### 六、证书使用示例 #### 1. 在HTTPS服务器中使用 将 `server.pem` 和 `server-key.pem` 配置到你的Web服务器(如Nginx、Apache): ```nginx server { listen 443 ssl; server_name server.example.com; ssl_certificate /path/to/server.pem; ssl_certificate_key /path/to/server-key.pem; ssl_client_certificate /path/to/ca.pem; # 客户端证书验证(可选) ssl_verify_client on; # 启用客户端证书验证(可选) # 其他配置... } ``` #### 2. 在客户端应用中使用 在需要验证服务器证书的客户端应用中,导入 `ca.pem` 作为信任的根证书。例如,使用curl访问HTTPS服务器: ```bash curl --cacert ca.pem https://server.example.com ``` ### 七、安全注意事项 1. **私钥保护**: - `ca-key.pem`、`server-key.pem` 和 `client-key.pem` 是敏感文件,应存储在安全位置 - 限制访问权限:`chmod 400 *.key.pem` 2. **证书备份**: - 定期备份CA证书和私钥 - 考虑使用硬件安全模块(HSM)存储CA私钥 3. **证书撤销**: - 如需撤销证书,可使用CFSSL生成证书撤销列表(CRL) - 更新 `ca-config.json` 添加CRL配置 通过以上步骤,你已成功创建了一个有效期10年的私有CA,并使用它签署了服务器和客户端证书。 ### 八、附快速签发脚本 ```bash #!/bin/bash # 证书快速签发脚本 # 依赖: cfssl, cfssljson 已安装并初始化好CA证书 # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' NC='\033[0m' # No Color # 默认配置 CA_KEY="/root/ckw/cfssl/ca/ca-ecdsa-key.pem" CA_CERT="/root/ckw/cfssl/ca/ca-ecdsa.pem" CA_CONFIG="/root/ckw/cfssl/ca/ca-config.json" OUTPUT_DIR="certs" MERGE_CA="true" # 默认合并根证书 # 使用帮助 function show_help { echo -e "${GREEN}证书快速签发脚本${NC}" echo "用法: $0 [选项]" echo "选项:" echo " -h, --help 显示此帮助信息" echo " -n, --name NAME 证书名称 (必填)" echo " -t, --type TYPE 证书类型: server, client, peer (默认: server)" echo " -c, --ca CA_CERT CA证书路径 (默认: $CA_CERT)" echo " -k, --ca-key CA_KEY CA私钥路径 (默认: $CA_KEY)" echo " -C, --ca-config CONF CA配置文件路径 (默认: $CA_CONFIG)" echo " -o, --output DIR 输出目录 (默认: $OUTPUT_DIR)" echo " -d, --domains LIST 域名列表 (逗号分隔)" echo "" echo "示例:" echo " $0 -n server1 -d example.com,www.example.com " } # 参数解析 NAME="" TYPE="server" DOMAINS="" while [[ $# -gt 0 ]]; do case $1 in -h|--help) show_help exit 0 ;; -n|--name) NAME="$2" shift 2 ;; -t|--type) TYPE="$2" shift 2 ;; -c|--ca) CA_CERT="$2" shift 2 ;; -k|--ca-key) CA_KEY="$2" shift 2 ;; -C|--ca-config) CA_CONFIG="$2" shift 2 ;; -o|--output) OUTPUT_DIR="$2" shift 2 ;; -d|--domains) DOMAINS="$2" shift 2 ;; --no-merge-ca) MERGE_CA="false" shift ;; *) echo -e "${RED}未知参数: $1${NC}" >&2 show_help exit 1 ;; esac done # 验证必填参数 if [[ -z "$NAME" ]]; then echo -e "${RED}错误: 必须指定证书名称 (-n/--name)${NC}" >&2 show_help exit 1 fi # 验证证书类型 if [[ "$TYPE" != "server" && "$TYPE" != "client" && "$TYPE" != "peer" ]]; then echo -e "${RED}错误: 证书类型必须是 server, client 或 peer${NC}" >&2 exit 1 fi # 验证文件是否存在 for file in "$CA_CERT" "$CA_KEY" "$CA_CONFIG"; do if [[ ! -f "$file" ]]; then echo -e "${RED}错误: 文件 $file 不存在${NC}" >&2 exit 1 fi done # 当类型为server且未指定域名时,默认将name作为域名 if [[ "$TYPE" == "server" && -z "$DOMAINS" ]]; then DOMAINS="$NAME" echo -e "${YELLOW}注意: 证书类型为server且未指定域名,默认添加 ${NAME} 作为域名${NC}" fi # 创建证书单独目录 CERT_DIR="$OUTPUT_DIR/$NAME" mkdir -p "$CERT_DIR" || { echo -e "${RED}无法创建证书目录: $CERT_DIR${NC}"; exit 1; } # 生成证书签名请求配置 CSR_CONFIG="$CERT_DIR/${NAME}-csr.json" cat > "$CSR_CONFIG" < "$FULL_CHAIN" echo -e "${GREEN}合并后的完整证书链: ${FULL_CHAIN}${NC}" fi # 显示证书信息 echo -e "\n${YELLOW}证书信息:${NC}" openssl x509 -noout -text -in "$CERT_DIR/${NAME}.pem" | grep -A 5 "Subject Alternative Name" else echo -e "${RED}证书生成失败!${NC}" exit 1 fi ```