使用openssl生成自签名证书以及nginx ssl双向验证

原创
2016/03/15 16:59
阅读数 4.5K

 

一、服务器端证书生成

1、生成服务器端的私钥

openssl genrsa -des3 -out server.key 2048

 

命令完成后会提示让输入密码,这个密码是通过des3(也可以采用其他加密算法)加密此密钥文件的,如果其他程序需要读取这个文件,需要输入密码

openssl rsa -in server.key -out server.key

执行这个命令后,NGINX引用此文件不需要输入密码

2、通过server.key生成证书

openssl req -new -key server.key -out server.csr

 

按照相关提示,填入证书相关基本信息,生成的证书通过CA签名后形成服务端自己的证书

(Certificate Signing Request(CSR))

二、客户端证书生成

1、生成客户端私钥

 openssl genrsa -des3 -out client.key 2048

2、通过client.key生成客户端证书

openssl req -new -key client.key -out client.csr

三、自签名

生成的csr文件必须要经过CA签名才能形成自己的证书,我们可以通过第三方权威认证机构进行签名,但是这个需要收费,我们制作自签名根证书

1、制作ca key文件和ca根证书

openssl req -new -x509 -keyout ca.key -out ca.crt

2、签署证书配置文件

查看/etc/pki/tls/openssl.cnf文件 ,查看dir是不是指向dir= /etc/pki/CA 如果不是,请修改

 

touch /etc/pki/CA/{index.txt,serial}

这个是根据openssl.cnf中的配置,要求生成的文件

----------------------------------

 

dir             = /etc/pki/CA           # Where everything is kept

certs           = $dir/certs            # Where the issued certs are kept

crl_dir         = $dir/crl              # Where the issued crl are kept

database        = $dir/index.txt        # database index file.

-------------------------------

echo 01 > /etc/pki/CA/serial

3、用第一步制作的证书,对服务器证书和客户端证书进行签名

 openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key

 

 openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key

 至此证书签名已经全部完毕。

四、证书导出

        由于我们生成的客户端证书是需要用在各个地方的,例如在浏览器中,在IOS和Android中,需要做相应的转换才能安装

        1、导出浏览器可以安装的证书

        openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12

        2、导出Android可以安装的证书

        openssl pkcs12 -export -in client.crt -inkey client.key -out  client.pfx

        3、导出IOS可以安装的证书

        openssl x509 -in client.crt -out client.cer
        
        另外IE也可以安装.pfx格式的证书
        
        以上步骤有些需要输入密码,密码就是我们刚才在生成客户端和浏览器端证书时的密码,密码千万必要忘记,忘记了只能重新生成
        
        client使用的文件有:ca.crt,client.crt,client.key,client.pfx
        server使用的文件有:ca.crt, server.crt,server.key

五、nginx Https双向校验配置

    修改nginx.conf文件
     server {
        listen       443 ssl;                                                    #https默认端口
        root /var/www/src;
        ssl on;                                                                                #开启https校验
        ssl_certificate ssl/server.crt;                                #服务端证书            
        ssl_certificate_key ssl/server.key;                        #服务端key
        #ssl_client_certificate ssl/client/client.crt;#客户端证书,不需要根证书的时候可以使用
        ssl_client_certificate ssl/ca.crt;                        #客户端签发的ca证书
        ssl_verify_client on;                                                    #开启对客户端的校验,这个地方是就是开启双向校验的地方

       ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;
    }

配置完成以后    nginx -s reload 使之生效

六、使用

    把相关证书导入到相应的客户端,例如在IE下,需要把根证书ca.crt安装到受信任的证书颁发机构
client.crt(client.pfx) 安装到个人证书的位置
然后打开我们需要访问的地址https://xxx.xxx.xxx.xx能正确的打开页面即代表成功
在打开的时候,浏览器会询问,1、证书确认,2、需要凭据(是否允许此应用访问您的私钥)
以上点击确认和允许即可

 

(ps:接下来我会一些脚本直接把以上带颜色的命令进行生成)

七、自动化脚本

通过以上命令,我写了一个shell脚本,可以快速的生成我们需要的证书,由于不能上传附件,所以写的shell文件就不能上传上来了,贴上具体的脚本代码,还请读者复制到自己的文件中然后进行运行即可

1、脚本代码

 

#!/bin/sh
# create self-signed server certificate:
read -p "请输入证书的域 例如[www.example.com or 192.168.1.52]: " DOMAIN

SUBJECT="/C=CN/ST=BJ/L=BJ/O=bky/CN=$DOMAIN"

echo "创建服务器证书..."

openssl genrsa -des3 -out server.key 2048
openssl rsa -in server.key -out server.key

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

echo "创建客户端证书..."
openssl genrsa -des3 -out client.key 2048
openssl req -new -subj $SUBJECT -key client.key -out client.csr

echo "创建根证书..."
openssl req -new -x509 -keyout ca.key -out ca.crt

rm -rf /etc/pki/CA/index.txt
rm -rf /etc/pki/CA/serial
touch /etc/pki/CA/{index.txt,serial}
echo 01 > /etc/pki/CA/serial

echo "用根证书对服务器证书和客户端证书签名"
openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key
openssl ca -in client.csr -out client.crt -cert ca.crt -keyfile ca.key

echo "导出服务器证书和客户端证书"
openssl pkcs12 -export -clcerts -in client.crt -inkey client.key -out client.p12
openssl pkcs12 -export -in client.crt -inkey client.key -out  client.pfx
openssl x509 -in client.crt -out client.cer
openssl x509 -in server.crt -out server.cer


echo "把以上生成的文件copy到nginx conf文件的ssl目录下面,如果ssl目录不存在请创建"
echo "接下请配置nginx.conf操作:"
echo " server {																						"
echo " 			...                                           "
echo "     ssl on;                                        "
echo "     ssl_certificate ssl/server.crt;                "
echo "     ssl_certificate_key ssl/server.key;            "
echo "     ssl_client_certificate ssl/ca.crt;             "
echo "     ssl_verify_client on;                          "
echo "			...                                           "
echo "     }                                               "
echo "使用如下命令重新加载nginx配置"
echo "nginx -s reload"

 

注意事项:

SUBJECT="/C=CN/ST=BJ/L=BJ/O=bky/CN=$DOMAIN"

这一部分需要改为和自己公司相符的内容,或者干脆直接更改为SUBJECT="/CN=$DOMAIN",然后在下面填写证书的时候再进行填写,如果使用了上述的SUBJECT,则在接下来填写证书信息,例如国家,城市,机构的时候必须要和这个相同,如果不相同,就会生不成server.crt证书文件。例如如果国家在SUBJECT中设置的是CN,而下面填写证书信息的时候不是CN,则执行openssl ca -in server.csr -out server.crt -cert ca.crt -keyfile ca.key的时候会报如下错误

The countryName field needed to be the same in the
CA certificate (cn) and the request (CN)

2、脚本碰到的问题

 

在运行以上脚本的时候出现了一个小问题,错误信息如下:

 

openssl TXT_DB error number 2 failed to update database

在网上搜了一下解决方法,借鉴一下:

 

产生的原因是:

This thing happens when certificates share common data. You cannot have two 
certificates that look otherwise the same.

方法一:

修改demoCA下 index.txt.attr

  1. unique_subject = yes 

 方法二:

删除demoCA下的index.txt,并再touch下

  1. rm index.txt  
  2.   
  3. touch index.txt

 方法三:

将 common name设置成不同的

 

 

展开阅读全文
打赏
2
10 收藏
分享
加载中
更多评论
打赏
0 评论
10 收藏
2
分享
返回顶部
顶部