一、写作目的
最近几天在用C语言+OpenSSL写支持Https的web服务器,可是由于没有证书(专业认证机构颁发要收费的,只是开发测试的话大可不必),所以需要自建CA证书和Server证书,服务器端SSL_accept操作又频繁出错,无法验证来自客户端的证书(稍后给出我的测试环境),所以额外生成Client证书。过段时间项目再打包到Github,暂时先说下证书的问题。
测试环境:
- 客户端:windows 10 64位 + chrome 64位正式版,ip地址:192.168.137.1
- 服务器:Ubuntu 20.04 64位 + gcc 9.3.0 + Openssl 1.1.1,ip地址:192.168.137.2
- 最终测试协议版本 TLS V1.3
本文能得到些什么文件:
- CA(认证机构): ca-cert.pem ca-cert.srl ca-key.pem ca.p12 ca-req.csr
- server: server-cert.pem server-key.pem server.p12 server-req.csr
- client: client-cert.pem client-key.pem client.p12 client-req.csr
二、操作步骤
- 安装OpenSSL的库
1
2
3sudo apt-get update
sudo apt-get install openssl
sudo apt-get install libssl-dev - 为避免生成的文件看起来很乱,先新建一些文件夹
1
2
3
4
5
6
7cd ~/
mkdir SSL
cd SSL/
mkdir ca server client
# 最终停留路径确保在 ~/SSL
cd ~/SSL/ - 生成CA证书
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24openssl genrsa -out ca/ca-key.pem 2048 # 此处2048改为1024会报错!!
openssl req -new -out ca/ca-req.csr -key ca/ca-key.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]:HuBei
Locality Name (eg, city) []:WuHan
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Person
Organizational Unit Name (eg, section) []:TestVersion
Common Name (e.g. server FQDN or YOUR name) []:aflyingfish
Email Address []:(回车跳过)
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []:(回车跳过) - 给证书签名
1 | # 3650表示有效期10年 |
1 | # 导出为浏览器支持的*.p12格式 |
- 生成Server私钥
1
openssl genrsa -out server/server-key.pem 2048
- 创建Server证书请求
1 | openssl req -new -out server/server-req.csr -key server/server-key.pem |
- 对Server证书签名,并导出*.p12格式
1 | # 签名 |
1 | # 导出*p12格式 |
- 生成Client私钥
1
openssl genrsa -out client/client-key.pem 2048
- 创建client证书请求
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22openssl req -new -out client/client-req.csr -key client/client-key.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 (必须与上面CA的输入对应一致)
State or Province Name (full name) [Some-State]:HuBei(必须与上面CA的输入对应一致)
Locality Name (eg, city) []:WuHan(必须与上面CA的输入对应一致)
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Person(必须与上面CA的输入对应一致)
Organizational Unit Name (eg, section) []:TestVersion
Common Name (e.g. server FQDN or YOUR name) []:aflyingfish
Email Address []:
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456
An optional company name []: - 对Client证书签名,并导出*.p12
1
2
3
4
5
6
7openssl x509 -req -in client/client-req.csr -out client/client-cert.pem -signkey client/client-key.pem -CA ca/ca-cert.pem -CAkey ca/ca-key.pem -CAcreateserial -days 3650
# 以下为输出信息:
Signature ok
subject=C = CN, ST = HuBei, L = WuHan, O = Person, OU = TestVersion, CN = aflyingfish
Getting Private key
Getting CA Private Key1
2
3
4
5openssl pkcs12 -export -clcerts -in client/client-cert.pem -inkey client/client-key.pem -out client/client.p12
# 以下为输出信息:
Enter Export Password:123456
Verifying - Enter Export Password:123456
三、验证证书有效性
- 验证Server有效性
1 | # 开启第一个终端 |
- 验证Client到server的连接
1 | # 终端一 |
四、证书的安装(windows上)
- 将“~/SSL/ca/ca.p12”,拷贝到windows上,双击–安装–本地计算机–输入密码(123456)–将所有证书都放入到下列路径存储–到受信任的根证书颁发机构–确定
- 将“~/SSL/client/client.p12”拷贝到windows上,双击–安装–本地计算机–输入密码(123456)–将所有证书都放入到下列路径存储–个人–确定
五、服务器上OpenSSL对证书的使用
基于证书,笔者与同学一起用C语言实现了简单的web server,支持http和https访问,GitHub项目地址:https://github.com/oneflyingfish/WebServer_C
1 | //以下程序记得修正证书路径 |