2. OpenSSL入门:安装、编译与核心配置

说实话,做PKI这一行,OpenSSL就是你的瑞士军刀。我入行那会儿,第一个任务就是编译OpenSSL——当时踩了不少坑,今天我把这些经验都摊开来讲。

2.1 安装与编译:别小看这一步

大部分Linux发行版都预装了OpenSSL,但版本往往偏旧。我个人习惯从源码编译,这样能精确控制功能开关和补丁。

2.1.1 快速安装(包管理器)

如果你只是测试或学习,用包管理器最省事:

# Debian/Ubuntu
sudo apt-get install openssl libssl-dev

# CentOS/RHEL
sudo yum install openssl openssl-devel

# macOS (Homebrew)
brew install openssl
小提示: 开发环境记得装 libssl-dev 或 openssl-devel,否则编译其他依赖OpenSSL的程序时会报错。我吃过这个亏。

2.1.2 源码编译(生产环境推荐)

为什么要自己编译?因为你可以选择是否支持SM2/SM3/SM4国密算法,也可以禁用掉不安全的旧协议。我曾经在客户现场遇到过因为OpenSSL版本太旧导致TLS 1.3握手失败的案例——从那以后,我坚持用源码编译。

# 下载源码(以1.1.1k为例)
wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz
tar -xzf openssl-1.1.1k.tar.gz
cd openssl-1.1.1k

# 配置(启用国密、禁用旧协议)
./config --prefix=/usr/local/openssl \
         --openssldir=/usr/local/openssl \
         enable-sm2 enable-sm3 enable-sm4 \
         no-ssl2 no-ssl3 no-rc5 no-md2

# 编译与安装
make -j$(nproc)
sudo make install

# 更新动态链接库
sudo ldconfig
注意: 编译前务必确认系统已安装 perl 和 make。另外,--prefix 和 --openssldir 最好保持一致,否则后续找配置文件会很痛苦。

2.2 常用命令概览:每天都会用到的那些

OpenSSL的命令行工具功能极其丰富,但日常工作中高频使用的其实就十几个。我把它们分成三类:

类别 命令 典型用途
密钥与证书 genrsa / ecparam 生成RSA或ECC私钥
req 生成CSR或自签名证书
x509 查看、转换、签名证书
验证与调试 verify 验证证书链
s_client 测试TLS握手(类似curl的调试版)
格式转换 pkcs12 PKCS#12(.p12/.pfx)与PEM互转
rsa / ec 私钥格式转换与加密

举个例子,查看一个证书的详细信息:

openssl x509 -in server.crt -text -noout

这个命令我每天至少用十次。你想想看,拿到一个证书,第一件事就是看它的签发者、有效期、SAN(主题备用名称)对不对。

避坑指南: 我曾经因为没加 -noout 参数,结果终端刷出了两屏的BASE64编码,差点以为证书坏了。记住,-text 输出人类可读信息,-noout 隐藏原始编码。

2.3 配置文件 openssl.cnf 解析

这是OpenSSL的灵魂。没有它,你连一个像样的CSR都生成不出来。我见过太多人直接跳过配置,结果生成的证书要么缺SAN,要么扩展字段全是错的。

2.3.1 配置文件结构

openssl.cnf 采用INI风格,分为几个核心段落:

[ req ]                    # 请求相关默认值
default_bits        = 2048
distinguished_name  = req_distinguished_name
req_extensions      = req_ext

[ req_distinguished_name ]  # DN字段定义
countryName             = Country Name (2 letter code)
countryName_default     = CN
stateOrProvinceName     = State or Province Name
localityName            = Locality Name
organizationName        = Organization Name
organizationalUnitName  = Organizational Unit Name
commonName              = Common Name

[ req_ext ]              # 请求扩展(SAN等)
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = example.com
DNS.2 = www.example.com

嗯,这里要注意:distinguished_name 指向的段落定义了证书主题(DN)的各个字段,而 req_extensions 指向的段落则定义了扩展属性——SAN就是放在这里的。

2.3.2 核心参数详解

参数 所在段落 作用 我的建议
default_bits [ req ] 默认密钥长度 2048起步,敏感系统用4096
distinguished_name [ req ] 指定DN模板段落 保持与组织规范一致
req_extensions [ req ] 指定扩展模板段落 必须配置,否则没有SAN
subjectAltName [ req_ext ] 定义SAN列表 浏览器强制要求,不配就报错
basicConstraints [ v3_ca ] 标记是否为CA证书 CA证书必须配 CA:TRUE
重要: 从Chrome 58开始,所有未包含 subjectAltName 的证书都会被标记为不安全。我去年帮一个客户排查问题,他们内部系统突然打不开,最后发现就是证书缺SAN。这个坑,千万别踩。

2.3.3 实战:生成一个带SAN的CSR

假设你有一个配置文件 my.cnf,内容如上。生成CSR的命令:

openssl req -new -key server.key -out server.csr -config my.cnf

验证CSR中的SAN:

openssl req -in server.csr -text -noout | grep -A 1 "Subject Alternative Name"

如果输出为空,说明你的配置没生效。我建议你检查一下 req_extensions 是否指向了正确的段落。

2.4 本章知识体系

下面这张图帮你理清OpenSSL的核心脉络:

OpenSSL核心知识体系 OpenSSL 核心知识体系 安装与编译 常用命令 openssl.cnf 包管理器 源码编译 密钥/证书 验证/调试 [ req ] 段落 扩展段落 三者缺一不可:编译决定能力,命令决定效率,配置决定正确性
核心要点: OpenSSL的安装决定了你能用什么算法,命令决定了你干活快不快,而配置文件决定了证书能不能用。我建议你先把 openssl.cnf 吃透,后面所有章节都离不开它。