操作步骤:
- 生成根CA证书并自签
- 生成二级CA证书并使用CA证书签发
- 生成服务器证书并使用二级CA证书签发
- 制作CA证书链
- 打包为p12文件
- 转化为keystore文件
1. 生成根CA证书并自签
openssl req -x509 -newkey rsa:2048 -nodes -keyout root-ca.key -out root-ca.crt -days 3650 -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=root-ca"
openssl x509 -in root-ca.crt -text -noout
2. 生成二级CA证书并使用CA证书签发
openssl req -new -newkey rsa:2048 -nodes -keyout secondary-ca.key -out secondary-ca.csr -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=secondary-ca"
openssl x509 -req -in secondary-ca.csr -CA root-ca.crt -CAkey root-ca.key -CAcreateserial -out secondary-ca.crt -days 3650
openssl x509 -in secondary-ca.crt -text -noout
3. 生成服务器证书并使用二级CA证书签发
openssl req -new -newkey rsa:2048 -nodes -keyout server.key -out server.csr -subj "/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=server"
openssl x509 -req -in server.csr -CA secondary-ca.crt -CAkey secondary-ca.key -CAcreateserial -out server.crt -days 3650
openssl x509 -in server.crt -text -noout
4. 制作CA证书链
cat root-ca.crt secondary-ca.crt > chain-ca.crt
5. 打包为p12文件
openssl pkcs12 -export -in server.crt -inkey server.key -chain -CAfile chain-ca.crt -name server -out server.p12 -password pass:changeit
openssl pkcs12 -in server.p12 -password pass:changeit
openssl pkcs12 -in server.p12 -nocerts -nodes -password pass:changeit
openssl pkcs12 -in server.p12 -clcerts -nokeys -password pass:changeit
openssl pkcs12 -in server.p12 -cacerts -nokeys -chain -password pass:changeit
执行后,将会显示三个公钥,然后要求输入密码,之后会显示私钥,总共4个文件的打包都在这个p12文件中了!内容如下:
MAC verified OK
Bag Attributes
friendlyName: server
localKeyID: 9B 11 E1 8F 2C E9 A6 09 9A B9 BC 7B 06 1A 43 E9 C5 C8 B6 5A
subject=/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=server
issuer=/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=secondary-ca
-----BEGIN CERTIFICATE-----
....
-----END CERTIFICATE-----
Bag Attributes: <No Attributes>
subject=/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=secondary-ca
issuer=/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=root-ca
-----BEGIN CERTIFICATE-----
....
-----END CERTIFICATE-----
Bag Attributes: <No Attributes>
subject=/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=root-ca
issuer=/C=CN/ST=shanghai/L=shanghai/O=example/OU=it/CN=root-ca
-----BEGIN CERTIFICATE-----
....
-----END CERTIFICATE-----
Bag Attributes
friendlyName: server
localKeyID: 9B 11 E1 8F 2C E9 A6 09 9A B9 BC 7B 06 1A 43 E9 C5 C8 B6 5A
Key Attributes: <No Attributes>
Enter PEM pass phrase:
Verifying - Enter PEM pass phrase:
-----BEGIN ENCRYPTED PRIVATE KEY-----
....
-----END ENCRYPTED PRIVATE KEY-----
6. 转化为keystore文件
keytool -importkeystore -deststorepass changeit -destkeystore server.jks -srckeystore server.p12 -srcstoretype PKCS12 -srcstorepass changeit -noprompt
keytool -list -v -keystore server.jks -v -storepass changeit
keytool -list -rfc -keystore server.jks -storepass changeit
要注意的是:
- server.jks只有一个entry:server
- 这个entry的类型是:Entry type: PrivateKeyEntry
对于PrivateKeyEntry类型要特别解释一下:该类型的官方解释是:它包含一个密钥,这个密钥是加密的,查看时也不会显示,也不能导出,但要清楚的是,这个私钥是实实在在存在。同时,它还会包含这个私钥对应的证书链!所以,转成server.jks的文件是包含了server.p12中的全部信息:一个私钥+3个证书组成的证书链!
参考Java官方文档: https://docs.oracle.com/javase/6/docs/api/java/security/KeyStore.html
最后:既然keystore文件无法导出密钥,一般的处理方法是先将其转为p12文件,然后就可以导出密钥了!
7. 注意事项
在第5步中,如果给-CAfile 传入的不是root-ca.crt 和secondary-ca.crt 拼接后chain-ca.crt 文件,而是给server.crt 直接授权的secondary-ca.crt 文件,命令行将会报错:
Error unable to get issuer certificate getting chain.
8. 使用openssl x509 和openssl ca 签发CA证书的差别
使用openssl x509 和使用openssl ca 没有本质差别,openssl ca 使用的配置文件,文件中配置固定的index.txt和serial文件,来记录签发过的证书,确保不会重复签发。如果把当前服务器作为专门的CA签发机构,使用openssl ca 及其关联的配置文件会更好一些。如果只是命令行临时生成一下,用openssl x509 完全可以满足需求。
此外,从测试来看,openssl x509 签发的只能是v1版本的,即使加了-extensions v3_ca也无效,但是openssl ca -extensions v3_ca 签发出来的就是v3版本的。
|