作为文件形式存在的证书,一般有三类: A. 包含有私钥的证书,包含了公钥和私钥,用pkcs12标准,而一般以pfx 作为扩展名; B. DER 编码证书,不含私钥,以cer 结尾,文件是二进制data. 通常CA(无论是intermediate CA还是root CA)证书都是这类; C. BASE64编码的证书,这类证书也不含私钥,一般也以cer结尾,是pem证书, 这类证书可以直接cat 出结果, 特征是”-----BEGIN CERTIFICATE----- “开头,“-----END CERTIFICATE-----”结尾;
对于DER/PEM证书,可以通过openssl 来确认其编码类型(假设要查看的证书是client_cert.cer): openssl x509 -in ./client_cert.cer -inform pem -noout -text openssl x509 -in ./client_ert.cer -inform der -noout -text
jks 是java key store 的简称,也就是java 常用的证书文件. jks 证书文件一般包含私钥以及签名的cert一起组成的. 要生成jks 可以使用java 的keytool工具 以及openssl 来完成,没有特殊需求的情况先,可以只用这两个工具就可以了:
基本的过程是这样的:
代码语言:javascript复制1. 我们生成私钥匙key 文件
2. 我们利用私钥和客户提供的信息生成 证书请求文件 csr文件
3. 把证书请求文件csr 发给 签发证书的team, 他们生成证书文件,类型一般是pem certificate 文件;在生成之后,他们需要把生成的这个perm证书文件,以及用于签发证书的 intermediate-CA ,还有root-CA 都发回给我们, CA 一般是DER编码的二进制证书
4. 拿到了pem 证书文件,以及intermediate-CA, root-CA 后,结合手里面的key 文件,然后生成pfx 证书文件;这时候需要注意的是:生成的证书必须是证书链形式存在, 也就是说,从root CA 到 intermediat-ca, 到cert 都要包含在里面;
5. 把pkf 证书转换成jks 证书,就成为了jks形式的证书了;然后就可以发送给客户使用;
具体的步骤如下:
代码语言:javascript复制1. 生成私钥key文件:
openssl genrsa -out my.key 2048
2. 生成证书请求文件:
openssl req -new -key my.key -out my.csr , 该命令是一个交互过程,需要提供如下参数:
C , S, L, O, OU, CN ; 分别是country, state, location, organization, organization unit, common name. 以及email address , 以上这些信息需要请求证书者进行提供; 这里需要注意的是,虽然keytool 和openssl 都可以生成证书请求文件csr, 但是有一些属性是openssl 不支持的,比如SAN信息,所以这时候还是需要使用keytool来生成csr文件;
上述创建私钥以及生成CSR的过程,可以用keytool工具来实现(MW的support 人员更乐于用keytool工具来实现),具体为:
代码语言:javascript复制1.
生成key以及keystore:
keytool -genkeypair -keyalg RSA -keysize 2048 -keystore "/root/.keystore" -alias "my.key"
其中keystore 的路径必须指定,否则会报错;另外不可少的参数是 加密算法(常用的是rsa 算法),以及keysize的大小;此时,生成的key文件默认就保存在keystore里面了,而-alias 参数看起来是可选的,但是也建议使用,以确保key 的名称;
在这里要注意的是: 有一个-genkeypair 以及 -genseckey的命令的却别,两者的不同是前一个采用DSA, 后一个采用DES算法; 如果使用 -genkeypair 后指定算法为DES,那么将会报错;上述命令是一个交互过程,完成后,就生成了keystore 文件;
最后需要注意的是:
1). 如果有SAN等信息,那么生成key的时候,需要使用如下的参数 -ext SAN=, 比如下面的参数值:
-ext SAN=dns:Hostname.myazure.biz,ip:10.11.4.4
2). 如果不想用交互模式,那么可以用如下类似的命令:
keytool -genkey -dname "CN=HOSTNAME.MYAZURE.BIZ,OU=SD DC,O=OP Compliance,L=LO,S=TO,C=VO,EMAILADDRESS=Myemail@163.com" -alias tomcat -keyalg RSA -keysize 2048 -keystore HOSTNAME.jks -validity 730 -ext SAN=dns:Hostname.myazure.biz,ip:10.11.4.4
2.
在上述创建keystore 的时候,就已经提供了CSR相关需求的信息,所以直接用如下的命令就可以生成csr 文件:
keytool -certreq -keyalg RSA -keystore "/root/.keystore" -file my.csr
如果keystore文件不存在,那么会失败;
3.
上述生成了csr 文件,但是key 还是在keystore 文件里面,需要用 如下的命令,将key export出来:
A. 首先把jks的keystore 转换成pkcs 的keystore.
keytool -v -importkeystore -srckeystore keystore.jks -srcstoretype jks -srcstorepass Welcome1 -destkeystore keystore.pfx -deststoretype pkcs12 -deststorepass Welcome1
B. 从pkcs12类型的keystore 里面export 出来key 文件;
openssl pkcs12 -in keystore.jks.p12 -nocerts -out keystore.key -nodes
上述步骤就成功创建了csr文件,并且成功获得了对应的private key. (无论是基于openssl 命令还是keytool命令) 然后需要将csr发送给证书签发者,然后证书签发者进行证书的签发; 签发后,一般会发回 crt 证书文件. 以及root ca, intermediate ca 还有签发的pem证书;
后面的步骤是创建证书链:
- 因为crt 证书一般是DER编码证书,所以要首先转成PEM证书;
查看der 编码的证书: openssl x509 -in ./Root-CA.cer -inform der -text -noout
转换der编码的证书为pem证书: openssl x509 -in ./Root-CA.cer -inform der -outform pem -out root.pem
反向转换pem证书为der证书: openssl x509 -in ./root.pem -inform pem -outform der -out root.cer
- 把签发的证书,root-ca, issuing-ca 一起做成证书链, 注意顺序,根正书在最后,签发的证书在最上面:
cat Mycert.cer Issuing-CA.crt Root-CA.crt > chain.cer #三个证书必须都是pem证书
- 至此,已经成功获得了含有完整证书链的证书,上文已经获得了key 文件;现在要把证书,key文件一起组成 pkcs12 证书,也就是包含私钥的证书:
openssl pkcs12 -export -out mykeystore.p12 -in chain.cer -inkey mykey.key -name "tomcat"
- 到上一步,已经成功获得了包含私钥的pkcs12类型的证书,最后一步是把pkcs12证书转换成 jks证书, 生成的 keystore.jks 里面就包含了证书以及私钥;
keytool -importkeystore -srckeystore keystore.p12 -srcstoretype PKCS12 -destkeystore keystore.jks -deststoretype JKS
查看证书: keytool -list -v -keystore test_keystore2.jks -storepass xoxoxo 查看证书请求文件: keytool -printcertreq -file www.mydomain.com_certreq.csr 查看已经签名的证书: keytool -printcert -file GlobalSign_cert.cer
如何通过本机简单验证ssl 证书是否正确呢? 用openssl 命令在本机开启ssl 的服务器和客户端,然后用ssl 方式进行连接进行验证:
- 在本机开启ssl 的服务端:
openssl s_server -msg -verify -tls1_2 -state -cert cert.cer -key privkey -accept 18444
- 在本机用ssl客户端:
openssl s_client -msg -verify -tls1_2 -state -showcerts -cert cert.cer -key privkey -connect localhost:18444
然后看输出的结果,就知道是否证书是ok的;
diff -eq <(openssl x509 -pubkey -noout -in mycert.crt) <(openssl rsa -pubout -in mycert.key)