使用openssl生成SSL证书完全参考手册

时间:2022-09-02 18:43:24

一般来说,配置HTTPS/SSL的步骤为:

1、生成足够强度的私钥。需要考虑:算法,广泛采用的一般是RSA。键长度,RSA默认为512,一般应选择2048。密码,虽然私钥不一定要加密存储,但是加密存储使得拿到私钥也没法直接使用。

2、创建CSR并发送给CA;

3、安装CA提供的证书到web服务器;

openssl是一个开放源代码的SSL实现。基于openssl指令的最简单和最主要应用就是使用req、CA和X509来签发一个证书。

ISO安全体系结构包括的五类安全服务包括:认证服务,访问控制服务,数据保密性,数据完整性,抗否认性。对应的安全机制为:认证机制(RSA、DSA)、数字签名机制(RSA、DSA),访问控制机制,加密机制(对称,非对称),数据完整性机制(MD5、SHA),公证机制。

openssl提供了命令行选项和交互式两种方式来执行各种操作。

在命令行中直接输入openssl可进入交互shell,如下:

[root@route local]# openssl
OpenSSL> help
openssl:Error: 'help' is an invalid command. Standard commands
asn1parse ca ciphers cms
crl crl2pkcs7 dgst dh
dhparam dsa dsaparam ec
ecparam enc engine errstr
gendh gendsa genpkey genrsa
nseq ocsp passwd pkcs12
pkcs7 pkcs8 pkey pkeyparam
pkeyutl prime rand req
rsa rsautl s_client s_server
s_time sess_id smime speed
spkac ts verify version
x509 Message Digest commands (see the `dgst' command for more details)
md2 md4 md5 rmd160
sha sha1 Cipher commands (see the `enc' command for more details)
aes-128-cbc aes-128-ecb aes-192-cbc aes-192-ecb
aes-256-cbc aes-256-ecb base64 bf
bf-cbc bf-cfb bf-ecb bf-ofb
camellia-128-cbc camellia-128-ecb camellia-192-cbc camellia-192-ecb
camellia-256-cbc camellia-256-ecb cast cast-cbc
cast5-cbc cast5-cfb cast5-ecb cast5-ofb
des des-cbc des-cfb des-ecb
des-ede des-ede-cbc des-ede-cfb des-ede-ofb
des-ede3 des-ede3-cbc des-ede3-cfb des-ede3-ofb
des-ofb des3 desx idea
idea-cbc idea-cfb idea-ecb idea-ofb
rc2 rc2-40-cbc rc2-64-cbc rc2-cbc
rc2-cfb rc2-ecb rc2-ofb rc4
rc4-40 seed seed-cbc seed-cfb
seed-ecb seed-ofb zlib

openssl的命令总体来说,分为3大类:标准或通用类、消息摘要类以及加解密类。

除了查看手册外,输入命令然后加上--help可以看到详细的选项说明,如下:

OpenSSL> ca --help
unknown option --help
usage: ca args -verbose - Talk alot while doing things
-config file - A config file
-name arg - The particular CA definition to use
-gencrl - Generate a new CRL
-crldays days - Days is when the next CRL is due
-crlhours hours - Hours is when the next CRL is due
-startdate YYMMDDHHMMSSZ - certificate validity notBefore
-enddate YYMMDDHHMMSSZ - certificate validity notAfter (overrides -days)
-days arg - number of days to certify the certificate for
-md arg - md to use, see openssl dgst -h for list
-policy arg - The CA 'policy' to support
-keyfile arg - private key file
-keyform arg - private key file format (PEM or ENGINE)
-key arg - key to decode the private key if it is encrypted
-cert file - The CA certificate
-selfsign - sign a certificate with the key associated with it
-in file - The input PEM encoded certificate request(s)
-out file - Where to put the output file(s)
-outdir dir - Where to put output certificates
-infiles .... - The last argument, requests to process
-spkac file - File contains DN and signed public key and challenge
-ss_cert file - File contains a self signed cert to sign
-preserveDN - Don't re-order the DN
-noemailDN - Don't add the EMAIL field into certificate' subject
-batch - Don't ask questions
-msie_hack - msie modifications to handle all those universal strings
-revoke file - Revoke a certificate (given in file)
-subj arg - Use arg instead of request's subject
-utf8 - input characters are UTF8 (default ASCII)
-multivalue-rdn - enable support for multivalued RDNs
-extensions .. - Extension section (override value in config file)
-extfile file - Configuration file with X509v3 extentions to add
-crlexts .. - CRL extension section (override value in config file)
-engine e - use engine e, possibly a hardware device.
-status serial - Shows certificate status given the serial number
-updatedb - Updates db for expired certificates
error in ca

可以执行version -a查看版本,如果是rpm/yum安装,则可以通过rpm -qa | grep openssl查看,如下:

OpenSSL> version -a
OpenSSL 1.0.1e-fips 11 Feb 2013
built on: Tue Jan 20 17:30:05 UTC 2015
platform: linux-x86_64
options: bn(64,64) md2(int) rc4(16x,int) des(idx,cisc,16,int) idea(int) blowfish(idx)
compiler: gcc -fPIC -DOPENSSL_PIC -DZLIB -DOPENSSL_THREADS -D_REENTRANT -DDSO_DLFCN -DHAVE_DLFCN_H -DKRB5_MIT -m64 -DL_ENDIAN -DTERMIO -Wall -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -Wa,--noexecstack -DPURIFY -DOPENSSL_IA32_SSE2 -DOPENSSL_BN_ASM_MONT -DOPENSSL_BN_ASM_MONT5 -DOPENSSL_BN_ASM_GF2m -DSHA1_ASM -DSHA256_ASM -DSHA512_ASM -DMD5_ASM -DAES_ASM -DVPAES_ASM -DBSAES_ASM -DWHIRLPOOL_ASM -DGHASH_ASM
OPENSSLDIR: "/etc/pki/tls"
engines: dynamic

因为使用openssl主要用于创建非对称加密的证书比如典型的用于web的https协议。非对称加密的算法主要有RSA和DSA,其他在用的较少,所以最好先了解下这两种算法的差别,这是有益无害的。

RSA 与 DSA 都是非对称加密算法。其中RSA的安全性是基于极其困难的大整数的分解(两个素数的乘积);DSA 的安全性是基于整数有限域离散对数难题。基本上可以认为相同密钥长度的 RSA 算法与 DSA 算法安全性相当。在RSA加解密中,公钥用于加密,它是向所有人公开的;私钥用于解密,只有密文的接收者持有。

在DSA数字签名和认证中,发送者使用自己的私钥对文件或消息进行签名,接受者收到消息后使用发送者的公钥来验证签名的真实性。

DSA只是一种算法,和RSA不同之处在于它不能用作加密和解密,也不能进行密钥交换,只用于签名,它比RSA要快很多.

所以RSA一般用于加解密,DSA则用于签名与验证。

openssl RSA的加解密过程如下:

生成一个密钥(私钥)
注意: 需要注意的是这个文件包含了公钥和密钥两部分,也就是说这个文件即可用来加密也可以用来解密,后面的1024是生成密钥的长度.
[root@route openssl]# openssl genrsa -out private.key 1024
Generating RSA private key, 1024 bit long modulus
.........................++++++
......................++++++
e is 65537 (0x10001)
通过密钥文件private.key 提取公钥
[root@route openssl]# openssl rsa -in private.key -pubout -out pub.key
writing RSA key
[root@route openssl]# ll
total 8
-rw-r--r-- 1 root root 891 Jan 15 18:54 private.key
-rw-r--r-- 1 root root 272 Jan 15 18:55 pub.key
使用公钥加密信息 下面仅仅是由于测试的目的,实际系统中这样使用并不是很多
[root@route openssl]# echo -n "this is a secret message" | openssl rsautl -encrypt -inkey pub.key -pubin > encrypt.out
[root@route openssl]# ll
total 12
-rw-r--r-- 1 root root 128 Jan 15 18:56 encrypt.out
-rw-r--r-- 1 root root 891 Jan 15 18:54 private.key
-rw-r--r-- 1 root root 272 Jan 15 18:55 pub.key
[root@route openssl]# cat encrypt.out
)YBϓSw
ѡ
ꝶ¸¼L׋A¦띭ۀi7f(°].ĝ蝤¤x8Tk/꠿ﳐv£ȩQꨆϟ¢k¬¼[k迼oX}D°[root@route openssl]# Xshell
-bash: Xshell: command not found
[root@route openssl]#
使用私钥解密信息 下面仅仅是由于测试的目的,实际系统中这样使用并不是很多
[root@route openssl]# cat encrypt.out | openssl rsautl -decrypt -inkey private.key this is a secret message[root@route openssl]# [root@route openssl]#

openssl DSA 签名与验证过程如下:

生成一个密钥(私钥)
[root@route openssl]# openssl dsaparam -out dsaparam.pem 1024
Generating DSA parameters, 1024 bit long prime
This could take some time
..+...+..........+.............+......................+...+.....+............+.......+..............................+.........+.................+......+............+..........+....+.....................................+.......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
....+..+...+........+......+............................................+..+.+.........+.........+...+.......+..................+....+...........................+....+...............+.+...............+....+..+..........+...........................................+......+.......+.+........+.........+...+.+.+....+.....+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*
[root@route openssl]# ll
total 16
-rw-r--r-- 1 root root 455 Jan 15 19:00 dsaparam.pem
-rw-r--r-- 1 root root 128 Jan 15 18:56 encrypt.out
-rw-r--r-- 1 root root 891 Jan 15 18:54 private.key
-rw-r--r-- 1 root root 272 Jan 15 18:55 pub.key
生成公钥
[root@route openssl]# openssl gendsa -out privkey.pem dsaparam.pem
Generating DSA key, 1024 bits
[root@route openssl]# openssl dsa -in privkey.pem -out pubkey.pem -pubout
read DSA key
writing DSA key
[root@route openssl]# ll
total 24
-rw-r--r-- 1 root root 455 Jan 15 19:00 dsaparam.pem
-rw-r--r-- 1 root root 128 Jan 15 18:56 encrypt.out
-rw-r--r-- 1 root root 891 Jan 15 18:54 private.key
-rw-r--r-- 1 root root 668 Jan 15 19:01 privkey.pem
-rw-r--r-- 1 root root 272 Jan 15 18:55 pub.key
-rw-r--r-- 1 root root 654 Jan 15 19:01 pubkey.pem
下面仅仅是由于测试的目的,实际系统中这样使用并不是很多
使用私钥签名
[root@route openssl]# echo -n "this is a secret message" | openssl dgst -dss1 -sign privkey.pem > sign.result
使用公钥验证
[root@route openssl]# echo -n "this is a secret message" | openssl dgst -dss1 -verify pubkey.pem -signature sign.result
Verified OK
[root@route openssl]#

有点类似于ip之于域名,加解密和签名是具体的实现,运行中通常使用证书(提到证书,平时各种地方见到最多的就是x.509了,实际上x.509是是由国际电联电信委员会(ITU-T)为单点登录(SSO-Single Sing-on)和授权管理基础设施(PMI-Privilege Management Infrastructure)制定的PKI标准(所以证书是PKI的基本建立块)。X.509定义了(但不仅限于)公钥证书、证书吊销清单、属性证书和证书路径验证算法等证书标准,所以证书是最后的表现方式。除了x.509外,另外一张格式是PKCS#8)作为载体完成安全认证。在HTTPS连接中,当SSL会话产生时,服务器会传送它的证书,用户端浏览器会自动分析服务器证书,并根据不同版本的浏览器,从而产生40位或128位的会话密钥,用于对交易的信息进行加密。所有的过程都会自动完成,对用户是透明的(如果客户端不是浏览器,则需要人工拷贝到对方,并使用编程语言各自对应的SDK进行加载和认证)。所以,还需要创建证书并部署到服务器上完成整个过程。

创建证书的完整逻辑过程为(如果是向第三方申请,则一般提交申请即可,第三方会将生成后的证书邮件方式发送给申请者):

1、创建CA 根证书;

2、生成CA自签名证书;

3、生成服务端CSR;

4、使用CA签名服务端证书;

使用openssl生成SSL证书的过程如下:

注意,首先在openssl.conf配置文件指定的目录创建下列文件,否则后面签名服务器证书的时候会失败。

index.txt  OpenSSL在创建自签证书时会向该文件里写下索引

database.txt  OpenSSL会模拟数据库将一些敏感信息写在该文件里

serial.txt  创建该文件后,请编辑在第一行写下 01

[root@route openssl]# openssl genrsa -des3 -out ca.key 1024
Generating RSA private key, 1024 bit long modulus
..++++++
...............++++++
e is 65537 (0x10001)
Enter pass phrase for ca.key:
Verifying - Enter pass phrase for ca.key:
# 生成 CA 的自签证书
[root@route openssl]# openssl req -new -x509 -key ca.key -out ca.crt -days 3650
Enter pass phrase for ca.key:
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) [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) []:ldtrader.com
Email Address []:
[root@route openssl]# ll
total 36
-rw-r--r-- 1 root root 928 Jan 15 19:13 ca.crt
-rw-r--r-- 1 root root 963 Jan 15 19:10 ca.key
-rw-r--r-- 1 root root 455 Jan 15 19:00 dsaparam.pem
-rw-r--r-- 1 root root 128 Jan 15 18:56 encrypt.out
-rw-r--r-- 1 root root 891 Jan 15 18:54 private.key
-rw-r--r-- 1 root root 668 Jan 15 19:01 privkey.pem
-rw-r--r-- 1 root root 272 Jan 15 18:55 pub.key
-rw-r--r-- 1 root root 654 Jan 15 19:01 pubkey.pem
-rw-r--r-- 1 root root 47 Jan 15 19:04 sign.result
[root@route openssl]# openssl genrsa -out server.key 1024
Generating RSA private key, 1024 bit long modulus
.........................++++++
.............................++++++
e is 65537 (0x10001)
[root@route openssl]# openssl req -new -key server.key -out server.csr
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) [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) []:ldtrader.com
Email Address []: Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:secret
An optional company name []:
[root@route openssl]# ll
total 44
-rw-r--r-- 1 root root 928 Jan 15 19:13 ca.crt
-rw-r--r-- 1 root root 963 Jan 15 19:10 ca.key
-rw-r--r-- 1 root root 455 Jan 15 19:00 dsaparam.pem
-rw-r--r-- 1 root root 128 Jan 15 18:56 encrypt.out
-rw-r--r-- 1 root root 891 Jan 15 18:54 private.key
-rw-r--r-- 1 root root 668 Jan 15 19:01 privkey.pem
-rw-r--r-- 1 root root 272 Jan 15 18:55 pub.key
-rw-r--r-- 1 root root 654 Jan 15 19:01 pubkey.pem
-rw-r--r-- 1 root root 664 Jan 15 19:14 server.csr
-rw-r--r-- 1 root root 887 Jan 15 19:14 server.key
-rw-r--r-- 1 root root 47 Jan 15 19:04 sign.result
[root@route openssl]# openssl ca -in server.csr -out server.crt -keyfile ca.key -cert ca.crt -days 3650
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for ca.key:
/etc/pki/CA/index.txt: No such file or directory
unable to open '/etc/pki/CA/index.txt'
139976169916232:error:02001002:system library:fopen:No such file or directory:bss_file.c:398:fopen('/etc/pki/CA/index.txt','r')
139976169916232:error:20074002:BIO routines:FILE_CTRL:system lib:bss_file.c:400:
[root@route openssl]# openssl ca -in server.csr -out server.crt -keyfile ca.key -cert ca.crt -days 3650
Using configuration from /etc/pki/tls/openssl.cnf
Enter pass phrase for ca.key:
wrong number of fields on line 1 (looking for field 6, got 1, '' left)

合并证书文件和私钥文件(典型的比如nginx就需要使用到pem格式)

cat server.crt server.key > server.pem

PS:在openssl以及更广泛的证书相关的文件中,各种文件格式及典型文件后缀约定如下:

.key格式:私有的密钥
.csr格式:证书签名请求(证书请求文件),含有公钥信息,certificate signing request的缩写
.crt格式:证书文件,certificate的缩写
.crl格式:证书吊销列表,Certificate Revocation List的缩写
.pem(Privacy-Enhanced Mail)格式:用于导出,导入证书时候的证书的格式,有证书开头,结尾的格式。

tomcat/nginx各自对证书的格式要求不同,各自配置如下:

http://www.cnblogs.com/zhjh256/p/6262620.html

http://www.cnblogs.com/zhjh256/p/6262575.html

补充一点,一般在正式的涉及金融相关的系统中,都会向第三方CA机构申请证书,在一些内部系统或者受众比较固定的系统中,有些会采用自签名的证书以节约成本,这没有问题,实现机制和安全强度应该不会差太多,更多的经营管理层面的考虑了。

编程手册可见如下:

https://www.openssl.org/docs/man1.0.1/

http://wenku.baidu.com/link?url=6nJ-Hgm18RAp8Q_dT_DT_AtnfzIt0MtBRNs7-PnAldBxKW709TEl1PhmHXh0xiM8tcZ9kS22ePtYiFxSjzObOnsdLEnEvwdHyBFlkeRs7G3

对openssl较好总结的文档为:

http://wenku.baidu.com/link?url=GTDC4s7RlnhF0ICV2VjwDfcniWpZqUN_O0OT6lX4zHC0lxPLN9l1bjAe86f2ywZGDt2rWe1ZW4-onSEc1CrWMqt-D3yF-p62Q9jRkTFulT3

SSL证书介绍:

http://baike.baidu.com/link?url=AdknAIGPZMEeeVBhccOVSQsBJDJWagr29LHJt8tnm6anNpbA6n4pfF4vGXtmr1eeGC1iXMI1fQtqdwlWK6tywa1HvxC8I4QneSZ_pIbWpPm

其他参考:

http://blog.sina.com.cn/s/blog_a9303fd90101cgw4.html

http://desert3.iteye.com/blog/1706194

http://blog.csdn.net/moonhillcity/article/details/52768218

http://www.cnblogs.com/asingna/p/5188944.html

http://www.zhimengzhe.com/php/157872.html

http://blog.csdn.net/moonhillcity/article/details/52768218