证书签发openssl

本文介绍如何使用OpenSSL建立私有证书颁发机构(CA)及签发证书的详细步骤,包括创建CA目录结构、生成CA密钥对、自签CA证书、生成用户证书请求及签发用户证书。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于 OpenSSL 的 CA 建立及证书签发

默认分类 2008-01-16 23:26:13 阅读4075 评论0   字号:   订阅

版权所有,如需转载请注明出处

前段时间研究了一下 SSL/TLS ,看的是 Eric Rescorla 的 SSL and TLS - Designing and Building Secure Systems 的中文版(关于该中文版的恶劣程度,我在之前的一篇 Blog 中已做了严厉的批判)。本书的作者沿袭了 Stevens 在其神作 TCP/IP Illustrated 中的思想:使用网络嗅探进行协议演示。不同的是,作者并没有使用 tcpdump ,而是使用了自己编写的专用于嗅探 SSL/TLS 通讯的 ssldump 。为了对书中的一些内容进行试验确认,我决定使用 ssldump 进行一些实验。然而,进行 SSL/TLS 通讯,至少需要一份 CA 签发的证书才可以得以完成,仅仅是做个实验,我自然不会花天价去买个证书,所以决定自己建 CA 签发证书。

然而,到今天为止,我也没有能够成功地利用 ssldump 嗅探出一个 SSL/TLS 通讯包。为啥?只因为用 OpenSSL 建立 CA 签发证书的过程太麻烦了,以至于我忙活了好久才勉强建了个 CA ,之后又由于其他的事情,耽搁了 ssldump 的实验,于是就一直没有下文了。

什么?有免费的知名 CA 可以提供证书?咳……这个,我也是事后才知道的……不过,利用 OpenSSL 建立 CA 及自行签发证书的过程倒是很值得一写。 OpenSSL 的 ca 命令实在是难用,难怪 ca (1) 的 manpage 中这样写到:

WARNINGS

The ca command is quirky and at times downright unfriendly.

The ca utility was originally meant as an example of how to do things in a CA. It was not supposed to be used as a full blown CA itself: nevertheless some people are using it for this purpose.

The ca command is effectively a single user command: no locking is done on the various files and attempts to run more than one ca command on the same database can have unpredictable results.

看来,我们这些非要用 OpenSSL 来做 CA 的人本来就是自找麻烦。不过,虽然 OpenSSL 的用户界面让人望而却步,就其功能而言,恐怕是各个相关 FOSS 产品中最为完备的一款,加之获取方便,在 Debian 下直接 aptitude install openssl 便可以安装, Win32 下的话,也可以方便地从在 cygwin 官方镜像站上获取。况且,作为信息安全方面的新手,我对其他相关产品也是一无所知。所以,还是硬着头皮去啃 OpenSSL 的 man 手册。利用了两三天的闲暇时间,在 kghost 的帮助下,我终于掌握了要点。下文便详细记录了基于 OpenSSL 的 CA 建立及证书签发过程。

建立 CA

建立 CA 目录结构

按照 OpenSSL 的默认配置建立 CA ,需要在文件系统中建立相应的目录结构。相关的配置内容一般位于 /usr/ssl/openssl.cnf 内,详情可参见 config (1) 。在终端中使用如下命令建立目录结构:

$ mkdir -p ./demoCA/{private,newcerts}
$ touch ./demoCA/index.txt
$ echo 01 > ./demoCA/serial

产生的目录结构如下:

.
`-- demoCA/
    |-- index.txt
    |-- newcerts/
    |-- private/
    `-- serial

生成 CA 证书的 RSA 密钥对

首先,我们要为 CA 建立 RSA 密钥对。打开终端,使用如下命令生成 RSA 密钥对:

$ openssl genrsa -des3 -out ./demoCA/private/cakey.pem 2048

参数解释

genrsa

用于生成 RSA 密钥对的 OpenSSL 命令。

-des3

使用 3-DES 对称加密算法加密密钥对,该参数需要用户在密钥生成过程中输入一个口令用于加密。今后使用该密钥对时,需要输入相应的口令。如果不加该选项,则不对密钥进行加密。

-out ./demoCA/private/cakey.pem

令生成的密钥对保存到文件 ./demoCA/private/cakey.pem

2048

RSA 模数位数,在一定程度上表征了密钥强度。

该命令输出如下,用户应输入自己的密钥口令并确认:

Generating RSA private key, 2048 bit long modulus
................................................+++
.........................+++
e is 65537 (0x10001)
Enter pass phrase for ./demoCA/private/cakey.pem:<enter your pass-phrase>

Verifying - Enter pass phrase for ./demoCA/private/cakey.pem:<re-enter your pass-phrase>

生成 CA 证书请求

为了获取一个 CA 根证书,我们需要先制作一份证书请求。先前生成的 CA 密钥对被用于对证书请求签名。

$ openssl req -new -days 365 -key ./demoCA/private/cakey.pem -out careq.pem

参数解释

req

用于生成证书请求的 OpenSSL 命令。

-new

生成一个新的证书请求。该参数将令 OpenSSL 在证书请求生成过程中要求用户填写一些相应的字段。

-days 365

从生成之时算起,证书时效为 365 天。

-key ./demoCA/private/cakey.pem

指定 ./demoCA/private/cakey.pem 为证书所使用的密钥对文件。

-out careq.pem

令生成的证书请求保存到文件 careq.pem

该命令将提示用户输入密钥口令并填写证书相关信息字段,输出如下:

Enter pass phrase for ./demoCA/private/cakey.pem:<enter you pass-phrase>
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
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:ZJ
Locality Name (eg, city) []:HZ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Some Ltd. Corp.
Organizational Unit Name (eg, section) []:Some Unit
Common Name (eg, YOUR name) []:Someone
Email Address []:some@email.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

对 CA 证书请求进行签名

在实际应用中,用户可以通过向知名 CA 递交证书请求来申请证书。但是在这里,我们需要建立的是一个根 CA ,只能由我们自己来对证书请求进行签名。所以我们让 OpenSSL 使用证书请求中附带的密钥对对该请求进行签名,也就是所谓的“ self sign ”:

$ openssl ca -selfsign -in careq.pem -out cacert.pem

参数解释

ca

用于执行 CA 相关操作的 OpenSSL 命令。

-selfsign

使用对证书请求进行签名的密钥对来签发证书。

-in careq.pem

指定 careq.pem 为证书请求文件。

-out ./demoCA/cacert.pem

指定 ./demoCA/cacert.pem 为输出的证书。

该命令要求用户输入密钥口令并输出相关证书信息,请求用户确认:

Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:<enter your pass-phrase>
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Jan 16 13:05:09 2008 GMT
            Not After : Jan 15 13:05:09 2009 GMT
        Subject:
            countryName = CN
            stateOrProvinceName = ZJ
            organizationName = Some Ltd. Corp.
            organizationalUnitName = Some Unit
            commonName = Someone
            emailAddress = some@email.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                75:F5:3C:CC:C1:5E:6D:C3:8B:46:A8:08:E6:EA:29:E8:22:7E:70:03
            X509v3 Authority Key Identifier:
                keyid:75:F5:3C:CC:C1:5E:6D:C3:8B:46:A8:08:E6:EA:29:E8:22:7E:70:03

Certificate is to be certified until Jan 15 13:05:09 2009 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

一步完成 CA 证书请求生成及签名

以上两个步骤可以合二为一。利用 ca 命令的 -x509 参数,通过以下命令同时完成证书请求生成和签名从而生成 CA 根证书:

$ openssl req -new -x509 -days 365 -key ./demoCA/private/cakey.pem -out ./demoCA/cacert.pem

参数解释

req

用于生成证书请求的 OpenSSL 命令。

-new

生成一个新的证书请求。该参数将令 OpenSSL 在证书请求生成过程中要求用户填写一些相应的字段。

-x509

生成一份 X.509 证书。

-days 365

从生成之时算起,证书时效为 365 天。

-key ./demoCA/private/cakey.pem

指定 cakey.pem 为证书所使用的密钥对文件。

-out ./demoCA/cacert.pem

令生成的证书保存到文件 ./demoCA/cacert.pem

该命令输出如下,用户应输入相应的字段:

Enter pass phrase for ./demoCA/private/cakey.pem:
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
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:ZJ
Locality Name (eg, city) []:HZ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Some Ltd. Corp.
Organizational Unit Name (eg, section) []:Some Unit
Common Name (eg, YOUR name) []:Someone
Email Address []:some@email.com

至此,我们便已成功建立了一个私有根 CA 。在这个过程中,我们获得了一份 CA 密钥对文件 ./demoCA/private/cakey.pem 以及一份由此密钥对签名的 CA 根证书文件 ./demoCA/cacert.pem ,得到的 CA 目录结构如下:

.
|-- careq.pem
`-- demoCA/
    |-- cacert.pem
    |-- index.txt

    |-- index.txt.attr
    |-- index.txt.old
    |-- newcerts/
    |   `-- 01.pem
    |-- private/
    |   `-- cakey.pem
    |-- serial
    `-- serial.old

注:如果在 CA 建立过程中跳过证书请求生成的步骤,则不会产生 careq.pem 文件。

签发证书

下面我们就可以利用建立起来的 CA 进行证书签发了。

生成用户证书 RSA 密钥对

参照 CA 的 RSA 密钥对生成过程,使用如下命令生成新的密钥对:

$ openssl genrsa -des3 -out userkey.pem
Generating RSA private key, 512 bit long modulus
....++++++++++++
...++++++++++++
e is 65537 (0x10001)
Enter pass phrase for userkey.pem:<enter your pass-phrase>
Verifying - Enter pass phrase for userkey.pem:<re-enter your pass-phrase>

生成用户证书请求

参照 CA 的证书请求生成过程,使用如下命令生成新的证书请求:

$ openssl req -new -days 365 -key userkey.pem -out userreq.pem
Enter pass phrase for userkey.pem:<enter your pass-phrase>
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
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:ZJ
Locality Name (eg, city) []:HZ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Some Ltd. Corp.
Organizational Unit Name (eg, section) []:Some Other Unit
Common Name (eg, YOUR name) []:Another
Email Address []:another@email.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

签发用户证书

现在,我们可以用先前建立的 CA 来对用户的证书请求进行签名来为用户签发证书了。使用如下命令:

$ openssl ca -in userreq.pem -out usercert.pem

参数解释

ca

用于执行 CA 相关操作的 OpenSSL 命令。

-in userreq.pem

指定用户证书请求文件为 userreq.pem

-out usercert.pem

指定输出的用户证书文件为 usercert.pem

该命令要求用户输入密钥口令并输出相关证书信息,请求用户确认:

Using configuration from /usr/lib/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:<enter your pass-phrase>
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 2 (0x2)
        Validity
            Not Before: Jan 16 14:50:22 2008 GMT
            Not After : Jan 15 14:50:22 2009 GMT
        Subject:
            countryName               = CN
            stateOrProvinceName       = ZJ
            organizationName          = Some Ltd. Corp.
            organizationalUnitName    = Some Other Unit
            commonName                = Another
            emailAddress              = another@email.com
        X509v3 extensions:
            X509v3 Basic Constraints:
                CA:FALSE
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
                97:E7:8E:84:B1:45:27:83:94:A0:DC:24:79:7B:83:97:99:0B:36:A9
            X509v3 Authority Key Identifier:
                keyid:D9:87:12:94:B2:20:C7:22:AB:D4:D5:DF:33:DB:84:F3:B0:4A:EC:A2

Certificate is to be certified until Jan 15 14:50:22 2009 GMT (365 days)
Sign the certificate? [y/n]:y


1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated

至此,我们便完成了 CA 的建立及用户证书签发的全部工作。 不妨把所有 shell 命令放到一起纵览一下:

# 建立 CA 目录结构
mkdir -p ./demoCA/{private,newcerts}
touch ./demoCA/index.txt
echo 01 > ./demoCA/serial

# 生成 CA 的 RSA 密钥对
openssl genrsa -des3 -out ./demoCA/private/cakey.pem 2048

# 生成 CA 证书请求
openssl req -new -days 365 -key ./demoCA/private/cakey.pem -out careq.pem

# 自签发 CA 证书
openssl ca -selfsign -in careq.pem -out ./demoCA/cacert.pem

# 以上两步可以合二为一
openssl req -new -x509 -days 365 -key ./demoCA/private/cakey.pem -out ./demoCA/cacert.pem

# 生成用户的 RSA 密钥对
openssl genrsa -des3 -out userkey.pem

# 生成用户证书请求
openssl req -new -days 365 -key userkey.pem -out userreq.pem

# 使用 CA 签发用户证书
openssl ca -in userreq.pem -out usercert.pem

了解了这些基础步骤之后,就可以通过脚本甚至 makefile 的方式来将这些工作自动化。 CA.plCA.sh 便是对 OpenSSL 的 CA 相关功能的简单封装,在 Debian 系统中,安装了 OpenSSL 后,可以在 /usr/lib/ssl/misc/ 目录下找到这两个文件。而 makefile 的解决方案则可以参考这里

<think>我们正在模拟证书签发过程,使用OpenSSL命令行工具。证书签发通常涉及以下步骤: 1. 生成根证书的私钥 2. 创建自签名的根证书(CA证书) 3. 生成服务器(或用户)证书的私钥 4. 创建服务器证书证书签名请求(CSR) 5. 使用根证书的私钥对服务器证书的CSR进行签名,生成服务器证书 下面我们逐步进行: ### 步骤1: 生成根证书的私钥 使用以下命令生成一个RSA私钥(例如,2048位): ```bash openssl genrsa -out ca.key 2048 ``` ### 步骤2: 创建自签名的根证书 使用上一步生成的私钥创建自签名的根证书(CA证书)。在生成证书时,需要提供一些信息(如国家、组织等): ```bash openssl req -new -x509 -days 3650 -key ca.key -out ca.crt ``` 执行此命令后,会提示输入一些信息,这些信息将被嵌入到根证书中。 ### 步骤3: 生成服务器证书的私钥 同样,生成一个用于服务器证书的私钥: ```bash openssl genrsa -out server.key 2048 ``` ### 步骤4: 创建服务器证书证书签名请求(CSR) 使用服务器私钥生成证书签名请求(CSR): ```bash openssl req -new -key server.key -out server.csr ``` 同样,需要输入一些信息(注意:这些信息不必与根证书相同,但通常一些字段如国家、组织等需要符合一定的规则)。 ### 步骤5: 使用根证书签发服务器证书 使用根证书的私钥和根证书对服务器证书的CSR进行签名: ```bash openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt ``` 这里: - `-CA` 指定根证书 - `-CAkey` 指定根证书的私钥 - `-CAcreateserial` 选项会生成一个序列号文件(ca.srl),用于记录下一个可用的序列号 ### 验证证书 我们可以验证服务器证书是否由根证书签发: ```bash openssl verify -CAfile ca.crt server.crt ``` ### 示例 假设我们模拟一个简单的CA和服务器证书签发过程,具体命令如下: 1. 生成CA私钥: ```bash openssl genrsa -out ca.key 2048 ``` 2. 生成自签名CA证书(有效期10年): ```bash openssl req -new -x509 -days 3650 -key ca.key -out ca.crt # 输入信息示例: # Country Name (2 letter code) []:CN # State or Province Name (full name) []:Beijing # Locality Name (eg, city) []:Beijing # Organization Name (eg, company) []:My CA # Organizational Unit Name (eg, section) []:Root CA # Common Name (eg, fully qualified host name) []:My CA # Email Address []:ca@example.com ``` 3. 生成服务器私钥: ```bash openssl genrsa -out server.key 2048 ``` 4. 生成服务器CSR: ```bash openssl req -new -key server.key -out server.csr # 输入信息示例(注意Common Name是服务器的域名,例如:www.example.com): # ... 其他信息可以不同,但Common Name要写服务器域名 ``` 5. 用CA证书签名服务器CSR: ```bash openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt ``` 6. 验证: ```bash openssl verify -CAfile ca.crt server.crt ``` 这样,我们就得到了: - `ca.key`: CA私钥 - `ca.crt`: CA证书(根证书) - `server.key`: 服务器私钥 - `server.csr`: 服务器证书签名请求(可保留或删除) - `server.crt`: 服务器证书(由CA签发) ### 注意事项 - 在实际应用中,CA的私钥必须严格保护,因为泄露CA私钥意味着可以签发任意证书。 - 上述过程是简化版,实际中可能还会涉及扩展项(如主题备用名称SAN)等,可以通过配置文件添加。 ### 添加扩展项(可选) 如果需要为服务器证书添加扩展项(例如subjectAltName),可以创建一个配置文件(如`server.ext`): ``` authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = www.example.com DNS.2 = example.com ``` 然后在签名时使用该配置文件: ```bash openssl x509 -req -days 3650 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -extfile server.ext ``` 这样生成的服务器证书就包含了SAN扩展。 §§相关问题§§ 1. 如何为OpenSSL生成的证书添加主题备用名称(SAN)? 2. 如何使用OpenSSL创建中间CA并签发证书? 3. 如何将根证书安装到系统信任库中? 4. OpenSSL命令中,`-CAcreateserial`参数的作用是什么? 5. 如何查看证书的详细信息(如有效期、颁发者、主题等)?</think>### OpenSSL命令行模拟证书签发过程 OpenSSL命令行工具模拟证书签发过程主要包括以下步骤: #### 1. 生成根证书(CA证书) ```bash # 生成CA私钥 openssl genrsa -out ca.key 2048 # 创建自签名根证书(有效期10年) openssl req -new -x509 -days 3650 -key ca.key -out ca.crt ``` 执行后会提示输入证书信息(国家/组织/通用名等),通用名建议使用`My Root CA`。 #### 2. 生成服务器证书请求(CSR) ```bash # 生成服务器私钥 openssl genrsa -out server.key 2048 # 创建证书签名请求(CSR) openssl req -new -key server.key -out server.csr ``` 在通用名(Common Name)处输入服务器域名(如`www.example.com`)。 #### 3. 签发服务器证书 ```bash # 使用CA证书签发服务器证书 openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt ``` 参数说明: - `-CAcreateserial`:生成唯一的序列号文件(`ca.srl`) - `-days 365`:证书有效期1年 - 输出`server.crt`为最终签发证书 #### 4. 验证证书链 ```bash # 验证证书是否由CA签发 openssl verify -CAfile ca.crt server.crt # 查看证书详细信息 openssl x509 -in server.crt -text -noout ``` #### 完整流程示例 ```bash # 生成CA openssl genrsa -out ca.key 2048 openssl req -new -x509 -days 3650 -key ca.key -out ca.crt # 生成服务器证书 openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt # 验证 openssl verify -CAfile ca.crt server.crt ``` #### 关键文件说明: | 文件 | 作用 | |------|------| | `ca.key` | CA私钥(需严格保密) | | `ca.crt` | 根证书(需分发给客户端) | | `server.key` | 服务器私钥 | | `server.csr` | 证书签名请求(可删除) | | `server.crt` | 最终服务器证书 | ### 常见问题解决 1. **证书验证失败**: ```bash # 添加CA信任链 cat ca.crt >> /etc/ssl/certs/ca-certificates.crt ``` 2. **缺少扩展属性**: 使用配置文件添加扩展(创建`ext.cnf`): ```ini [ req ] req_extensions = v3_req [ v3_req ] subjectAltName = @alt_names [ alt_names ] DNS.1 = www.example.com ``` 签发时添加:`-extfile ext.cnf -extensions v3_req` 3. **密钥格式转换**(如需要PKCS#12格式): ```bash openssl pkcs12 -export -out server.p12 -inkey server.key -in server.crt ``` > 注意:生产环境应使用更安全的椭圆曲线密钥(如`openssl ecparam -genkey -name prime256v1`),并设置合理的证书有效期[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值