自签名证书制作

客户那边需要使用https来访问系统,简单制作了一个自签证书。

首先简单介绍下证书:

SSL使用证书来创建安全连接。有两种验证模式:

  • 仅客户端验证服务器的证书,客户端自己不提供证书;
  • 客户端和服务器都互相验证对方的证书。

显然第二种方式安全性更高,一般用网上银行会这么搞,但是,普通的Web网站只能采用第一种方式。

客户端如何验证服务器的证书呢?服务器自己的证书必须经过某“权威”证书的签名,而这个“权威”证书又可能经过更权威的证书签名,这么一级一级追溯上去,最顶层那个最权威的证书就称为根证书。根证书直接内置在浏览器中,这样,浏览器就可以利用自己自带的根证书去验证某个服务器的证书是否有效。

如果要提供一个有效的证书,服务器的证书必须从VeriSign这样的证书颁发机构签名,这样,浏览器就可以验证通过,否则,浏览器给出一个证书无效的警告。

申请一个证书签名的费用是一年几十~几百刀不等,所以如果只是出于管理目的,可以创建自签名证书,保证管理员通过浏览器安全连接到服务器。

以下是具体制作的流程,步骤如下:

第一步:使用OpenSSL创建证书

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#建立服务器私钥(过程需要输入密码,请记住这个密码)生成RSA密钥
>openssl genrsa -des3 -out server.key 1024
#生成一个证书请求
>openssl req -new -key server.key -out server.csr
#需要依次输入国家,地区,组织,email。最重要的是有一个common name,可以写你的名字或者域名。如果为了https申请,这个必须和域名吻合,否则会引发浏览器警报。生成的csr文件交给CA签名后形成服务端自己的证书
#---------------------------------------------------------------------------------------------------------------
Enter pass phrase for server.key: #之前输入的密码
Country Name (2 letter code) [XX]: #国家
State or Province Name (full name) []: #区域或是省份
Locality Name (eg, city) [Default City]: #地区局部名字
Organization Name (eg, company) [Default Company Ltd]: #机构名称:填写公司名
Organizational Unit Name (eg, section) []: #组织单位名称:部门名称
Common Name (eg, your name or your server's hostname) []: #网站域名
Email Address []: #邮箱地址
A challenge password []: #输入一个密码,可直接回车
An optional company name []: #一个可选的公司名称,可直接回车
#---------------------------------------------------------------------------------------------------------------
#输入完这些内容,就会在当前目录生成server.csr文件
>cp server.key server.key.org
>openssl rsa -in server.key.org -out server.key
#使用上面的密钥和CSR对证书进行签名
#以下命令生成v1版证书
>openssl x509 -req -days 365 -sha256 -in server.csr -signkey server.key -out servernew.crt
#以下命令生成v3版证书
>openssl x509 -req -days 365 -sha256 -extfile openssl.cnf -extensions v3_req -in server.csr -signkey server.key -out servernew.crt

v3版证书另需配置文件openssl.cnf,该文件内容详见博客https://blog.51cto.com/cangzihu/1879644

查看key、csr及证书信息

1
2
3
openssl rsa -noout -text -in myserver.key
openssl req -noout -text -in myserver.csr
openssl x509 -noout -text -in ca.crt

不同格式证书的转换

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# PKCS转换为PEM
> openssl pkcs12 -in myserver.pfx -out myserver.pem -nodes

# PEM转换为DER
> openssl x509 -outform der -in myserver.pem -out myserver.[der|crt]

# PEM提取KEY
> openssl RSA -in myserver.pem -out myserver.key

# DER转换为PEM
> openssl x509 -inform der -in myserver.[cer|crt] -out myserver.pem

# PEM转换为PKCS
> openssl pkcs12 -export -out myserver.pfx -inkey myserver.key -in myserver.pem -certfile ca.crt

Nginx下ssl配置方法

首先,确保安装了OpenSSL库,并且安装Nginx时使用了–with-http_ssl_module参数。

证书拷至nginx目录,配置如下server]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
server {
    listen 443 ssl;
    server_name your.domain.name;
    index index.html index.htm index.php;
    ssl on;
    ssl_certificate      ssl/server.crt;
    ssl_certificate_key  ssl/server.key;
    ssl_session_cache    shared:SSL:10m;
    ssl_session_timeout 5m;
    ssl_protocols    TLSv1 TLSv1.1 TLSv1.2;
}

另,还可加入如下配置实现https重定向

server {
isten 80;
server_name your.domain.name;
rewrite ^(.*) https://$server_name$1 permanent;
}

制作脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/bin/sh

# create self-signed server certificate:

read -p "Enter your domain [www.example.com]: " DOMAIN

echo "Create server key..."

openssl genrsa -des3 -out $DOMAIN.key 1024

echo "Create server certificate signing request..."

SUBJECT="/C=US/ST=Mars/L=iTranswarp/O=iTranswarp/OU=iTranswarp/CN=$DOMAIN"

openssl req -new -subj $SUBJECT -key $DOMAIN.key -out $DOMAIN.csr

echo "Remove password..."

mv $DOMAIN.key $DOMAIN.origin.key
openssl rsa -in $DOMAIN.origin.key -out $DOMAIN.key

echo "Sign SSL certificate..."

openssl x509 -req -days 3650 -in $DOMAIN.csr -signkey $DOMAIN.key -out $DOMAIN.crt

echo "TODO:"
echo "Copy $DOMAIN.crt to /etc/nginx/ssl/$DOMAIN.crt"
echo "Copy $DOMAIN.key to /etc/nginx/ssl/$DOMAIN.key"
echo "Add configuration in nginx:"
echo "server {"
echo " ..."
echo " listen 443 ssl;"
echo " ssl_certificate /etc/nginx/ssl/$DOMAIN.crt;"
echo " ssl_certificate_key /etc/nginx/ssl/$DOMAIN.key;"
echo "}"

红色部分是输入,注意4次输入的口令都是一样的。

在当前目录下会创建出4个文件:

www.test.com.crt:自签名的证书
www.test.com.csr:证书的请求
www.test.com.key:不带口令的Key
www.test.com.origin.key:带口令的Key
Web服务器需要把www.test.com.crt发给浏览器验证,然后用www.test.com.key解密浏览器发送的数据,剩下两个文件不需要上传到Web服务器上。

参考文章

  1. https://www.liaoxuefeng.com/article/990311924891552
  2. https://blog.51cto.com/cangzihu/1879657