PHP openssl_sign_csr签名证书丢失X509属性的问题求助
解决OpenSSL签名CSR时保留扩展并自动填充SAN的问题
1. 修正OpenSSL配置文件
创建或调整CA配置文件(示例命名为ca.conf),核心配置如下:
[ ca ] default_ca = CA_default [ CA_default ] # 替换为你的CA文件实际路径 dir = ./local_ca certificate = $dir/ca_cert.pem private_key = $dir/private/ca_key.pem default_md = sha256 # 关键配置:复制CSR中的所有扩展到证书 copy_extensions = copy policy = policy_loose [ policy_loose ] countryName = optional stateOrProvinceName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional [ usr_cert ] basicConstraints = CA:FALSE subjectKeyIdentifier = hash authorityKeyIdentifier = keyid,issuer # 复制CSR中的密钥用法,无则用默认值 keyUsage = copy # 复制CSR中的扩展密钥用法,无则启用服务器/客户端身份识别 extendedKeyUsage = copy,serverAuth,clientAuth # 复制CSR中的SAN扩展 subjectAltName = copy
2. 处理无SAN时自动用CN填充的逻辑
在签名脚本中添加前置检查,判断CSR是否包含SAN,无则提取CN并通过环境变量传递给OpenSSL:
# 替换为你的CSR文件路径 CSR_FILE="target.csr" # 检查CSR是否存在SAN扩展 has_san=$(openssl req -in "$CSR_FILE" -text -noout | grep -qi "subject alternative name" && echo 1 || echo 0) if [ "$has_san" -eq 0 ]; then # 提取CSR中的CN字段 cn_val=$(openssl req -in "$CSR_FILE" -subject -noout | sed -E 's/.*CN=([^,]+).*/\1/') # 设置环境变量用于生成SAN export OPENSSL_SAN="DNS:$cn_val" # 临时修改配置,优先使用环境变量的SAN值 sed -i 's/subjectAltName = copy/subjectAltName = ${ENV::OPENSSL_SAN}/' ca.conf else # 恢复配置为复制CSR的SAN模式 sed -i 's/subjectAltName = ${ENV::OPENSSL_SAN}/subjectAltName = copy/' ca.conf fi
3. 执行签名命令
运行OpenSSL CA命令完成签名:
openssl ca -config ca.conf -in "$CSR_FILE" -out signed_cert.pem -batch
4. 验证结果
检查签名后的证书是否包含所需扩展:
openssl x509 -in signed_cert.pem -text -noout
确认两点:
X509v3 Extended Key Usage包含CSR指定的(或默认的)服务器/客户端身份识别项X509v3 Subject Alternative Name正确显示CSR中的SAN,无SAN时显示CN对应的DNS条目
关键注意事项
- 先通过
openssl req -in target.csr -text -noout确认CSR中确实存在所需的扩展字段 copy_extensions = copy必须放在[CA_default]段才能全局生效,旧版OpenSSL可尝试copyall替代- 脚本中的sed命令需根据实际配置文件路径调整,避免误修改
内容的提问来源于stack exchange,提问作者Craig B
相关产品推荐
相关产品推荐

