什么是 CSR?#
CSR(Certificate Signing Request,证书签名请求) 是申请 SSL/TLS 证书时向证书颁发机构(CA)提交的文件。它包含了申请者的公钥和身份信息,由申请者的私钥签名。
CSR 的用途#
- 申请 SSL/TLS 证书 - 向 CA 提交 CSR 申请服务器证书
- 身份验证 - CSR 中的信息用于验证申请者身份
- 密钥关联 - 将公钥与域名/组织信息绑定
CSR 包含哪些信息?#
一个标准的 CSR 包含以下信息:
| 字段 |
说明 |
示例 |
| C (Country) |
国家代码 |
CN |
| ST (State) |
州/省 |
Beijing |
| L (Locality) |
城市 |
Beijing |
| O (Organization) |
组织名称 |
Example Corp |
| OU (Organization Unit) |
部门 |
IT Department |
| CN (Common Name) |
通用名称/域名 |
example.com |
| emailAddress |
电子邮件 |
admin@example.com |
此外,CSR 还包含:
- 公钥 - 与私钥配对的公钥
- 签名 - 使用私钥生成的数字签名
- 可选扩展 - 如 Subject Alternative Name (SAN)
使用 OpenSSL 生成 CSR#
基本命令格式#
1
2
3
4
5
|
# 生成私钥的同时生成 CSR(交互式)
openssl req -new -newkey rsa:2048 -nodes -keyout domain.key -out domain.csr
# 从现有私钥生成 CSR
openssl req -new -key domain.key -out domain.csr
|
示例 1:交互式生成 CSR#
1
|
openssl req -new -key example.key -out example.csr
|
系统会提示输入以下信息:
1
2
3
4
|
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank.
|
示例 2:非交互式生成 CSR(推荐)#
使用 -subj 参数直接指定信息:
1
2
|
openssl req -new -key example.key -out example.csr \
-subj "/C=CN/ST=Beijing/L=Beijing/O=Example Corp/OU=IT Department/CN=example.com/emailAddress=admin@example.com"
|
生成的 CSR 内容示例#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
-----BEGIN CERTIFICATE REQUEST-----
MIIC3jCCAcYCAQAwgZgxCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdCZWlqaW5nMRAw
DgYDVQQHDAdCZWlqaW5nMRUwEwYDVQQKDAxFeGFtcGxlIENvcnAxFjAUBgNVBAsM
DUlUIERlcGFydG1lbnQxFDASBgNVBAMMC2V4YW1wbGUuY29tMSAwHgYJKoZIhvcN
AQkBFhFhZG1pbkBleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
AQoCggEBAI7KZrtDB8A6JG3ba6u8snK2CVrkOXScjWt+KrjTaOQouuuN0L6cb32J
u7BZSpnLzXcXpjZeQUG3f1mhlD6/d334G8EYMxiNCkeQwTLOaE4IBJ1an7fJxcSp
/5pCTdh+iMsh9BrS9vaaOthnGb9wYunRlOF4yGSaHpbZbeu1Z/AgEL71EzyM8MXb
kgvnUc5Opc2mlbptkp9b3xn71fSY8zxzpyCmwjkbdB+1F1EMBsxhhOTy+oRE9DGm
4Mb6frP6R8mgG1wElqMrEZzLO6E0Y3nLTXKug9j43Lm9DttLGj9u66K2Uv7k8R9a
j2OehmUNHqlflwSK6j89YefFH5Q4DrkCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IB
AQB5vKA0vxZf1QGgn6Ev6IbrrHhlF3nOprmVAtFu5Q12kvLZwdXixpuGs3l1lqZm
YgX+m46N/mTMKujul//BVtfyItwIIatIapGU5xP0p/Bpel/M9oHxuHkcDHE9cIhq
L2fFaYz8GQZa/VDCfl2sy72bV/C6qT4Ij/6NTgPtbFwko2XlL3v1hyT4k7JmIDAV
pEsEjUpWL5SS2IvPuKsUcQH3bzeNTs0inQkh1OQndxQe+akVeb+BCPuMMrm6Tsh5
RCq+uw9nj2XAPeYanzhkn2dIC5GZHKLuVEyixQB7Yw8XFFK3yVdDc+yVNwIZ0sfv
xNrlucr7Ro9grbczX7J3FBtO
-----END CERTIFICATE REQUEST-----
|
查看 CSR 信息#
查看详细内容#
1
|
openssl req -in example.csr -noout -text
|
输出示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C = CN, ST = Beijing, L = Beijing, O = Example Corp, OU = IT Department, CN = example.com, emailAddress = admin@example.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:8e:ca:66:bb:43:07:c0:3a:24:6d:db:6b:ab:bc:
b2:72:b6:09:5a:e4:39:74:9c:8d:6b:7e:2a:b8:d3:
68:e4:28:ba:eb:8d:d0:be:9c:6f:7d:89:bb:b0:59:
4a:99:cb:cd:77:17:a6:36:5e:41:41:b7:7f:59:a1:
...
Exponent: 65537 (0x10001)
Attributes:
(none)
Requested Extensions:
Signature Algorithm: sha256WithRSAEncryption
Signature Value:
79:bc:a0:34:bf:16:5f:d5:01:a0:9f:a1:2f:e8:86:eb:ac:78:
...
|
仅查看 Subject 信息#
1
|
openssl req -in example.csr -noout -subject
|
输出:
1
|
subject=C = CN, ST = Beijing, L = Beijing, O = Example Corp, OU = IT Department, CN = example.com, emailAddress = admin@example.com
|
验证 CSR 签名#
1
|
openssl req -in example.csr -noout -verify
|
输出:
1
|
Certificate request self-signature verify OK
|
生成带 SAN 的 CSR#
SAN(Subject Alternative Name) 允许一个证书保护多个域名。现代浏览器要求证书包含 SAN 扩展。
步骤 1:创建配置文件#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
cat > san.cnf << 'EOF'
[req]
default_bits = 2048
distinguished_name = req_distinguished_name
req_extensions = req_ext
prompt = no
[req_distinguished_name]
C = CN
ST = Shanghai
L = Shanghai
O = Tech Company
CN = www.example.com
[req_ext]
subjectAltName = @alt_names
[alt_names]
DNS.1 = www.example.com
DNS.2 = example.com
DNS.3 = api.example.com
IP.1 = 192.168.1.100
EOF
|
步骤 2:使用配置文件生成 CSR#
1
2
3
4
|
openssl req -new -newkey rsa:2048 -nodes \
-keyout san-example.key \
-out san-example.csr \
-config san.cnf
|
验证 SAN 扩展#
1
|
openssl req -in san-example.csr -noout -text | grep -A1 "Subject Alternative Name"
|
输出:
1
2
|
X509v3 Subject Alternative Name:
DNS:www.example.com, DNS:example.com, DNS:api.example.com, IP Address:192.168.1.100
|
使用 ECC 密钥生成 CSR#
ECC(椭圆曲线加密)密钥比 RSA 更小、更高效。
生成 ECC 私钥和 CSR#
1
2
3
4
5
6
|
# 生成 ECC 私钥(P-256 曲线)
openssl ecparam -genkey -name prime256v1 -noout -out ecc.key
# 使用 ECC 私钥生成 CSR
openssl req -new -key ecc.key -out ecc.csr \
-subj "/C=JP/ST=Tokyo/L=Tokyo/O=ECC Test/CN=ecc.example.com"
|
ECC CSR 信息#
1
2
3
4
5
6
7
8
9
10
|
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C = JP, ST = Tokyo, L = Tokyo, O = ECC Test, CN = ecc.example.com
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
ASN1 OID: prime256v1
NIST CURVE: P-256
Signature Algorithm: ecdsa-with-SHA256
|
常用命令速查#
| 命令 |
说明 |
openssl req -new -key domain.key -out domain.csr |
从现有私钥生成 CSR |
openssl req -new -newkey rsa:2048 -nodes -keyout domain.key -out domain.csr |
同时生成私钥和 CSR |
openssl req -in domain.csr -noout -text |
查看 CSR 详细信息 |
openssl req -in domain.csr -noout -subject |
仅查看 Subject |
openssl req -in domain.csr -noout -verify |
验证 CSR 签名 |
openssl req -new -key ecc.key -out ecc.csr -subj "..." |
非交互式生成 CSR |
openssl ecparam -genkey -name prime256v1 -noout -out ecc.key |
生成 ECC 私钥 |
最佳实践#
- 密钥长度 - RSA 建议 2048 位或以上,ECC 推荐 P-256 或 P-384
- 私钥保护 - 生成私钥时使用
-nodes 参数要谨慎,生产环境建议加密私钥
- SAN 扩展 - 现代证书必须包含 SAN,CN 已被弃用作为域名验证依据
- 私钥安全 - 私钥绝不能发送给 CA,只需提交 CSR 文件
- 验证 CSR - 提交给 CA 前务必验证 CSR 内容正确
参考来源#