博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
数字证书、公私钥小记
阅读量:7087 次
发布时间:2019-06-28

本文共 2300 字,大约阅读时间需要 7 分钟。

术语

  • X.509

在密码学中,X.509是由ITU-T为了公开密钥基础建设(PKI)与授权管理基础建设(PMI)提出的产业标准。X.509标准,规范了公开密钥认证、证书吊销列表、授权证书、证书路径验证算法等。[1]

  • PKCS(Public Key Cryptography Standards)

PKCS是由RSA公司制定的一组关于公钥加密的标准,和存储相关的主要包括:

PKCS1:定义了RSA的数理基础、公私钥格式,以及加解密、签/验章的流程PKCS8:定义了私钥消息的表示PKCS12:定义了包含私钥与公钥证书的文件格式,其中私钥采密码保护

公私钥及证书的生成

以下操作会用到opensslkeytool两个工具。注意,如果不加声明,证书和密钥的存储都是PEM格式。

生成私钥

openssl genrsa -out ca.key 2048

openssl生成的私钥是按PKCS#1编码的,这种格式包括了密钥的所有信息(如n、e、d、p、q等)[2],所以genrsa只生成私钥。

如果需要PKCS\#8编码的私钥,还需要额外的转换:

openssl pkcs8 -topk8 -inform PEM in ca.key -outform PEM -nocrypt -out ca.pkcs8.key

如果需要公钥,需要使用如下的命令:

从私钥得到公钥

openssl rsa -in ca.key -pubout -outform PEM -out ca.pub

生成的公钥是按PKCS#8编码的。大多数地方都采用这种格式表示公钥。

生成根证书

openssl req -x509 -new -nodes -key ca.key -days 3000 -out ca.crt

生成的证书是按X.509编码的,有效期是3000天。

签发证书

有了根证书,就可以对证书签名了。为此,你需要先生成一个私钥,例如叫做host.key,然后通过私钥创建一个签名请求(CSR):

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

openssl会问你一些问题,务必注意CN这个选项,它应当是放置该证书的主机名(域名或者IP地址),如果开启了证书校验,它必须跟客户端建立连接时填写的host一致。

有了CSR,就可以用根证书和它的密钥来签发证书了:

openssl x509 -req -in host.csr -CA ca.crt -CAkey ca.key -CAcreateserial -days 1000 -out host.crt

证书依旧是按X.509编码的,有效期是1000天。

证书格式的转换

以上生成的公私钥和证书都是PEM格式的,但很多时候不同场景中还需要用到其他格式的证书:

p12/pfx

p12/pfx是按照PKCS#12编码的对象,它通常由X.509证书和对应的私钥组成。生成p12格式的方法如下:

openssl pkcs12 -export -in ca.crt -inkey ca.key -out ca.p12

由于文件中保存了私钥,因此执行该命令,openssl会要求用户输入密码,用于保护私钥。

jks

在Java中,免不了使用JKS格式,JKS是Java标准的密钥和证书保存格式,严格来说,Java的KeyStore存储的是多个密钥和证书。要生成它,需要用到keytool工具:

p12文件转换为jks

keytool -importkeystore -srckeystore cert.p12 -srcstoretype pkcs12 -destkeystore cert.jks

分别输入目标jks文件的密码和源p12文件的密码,即可生成。

crt文件转换为jks

keytool -import -file ca.crt -keystore ca.jks

不同环境/工具对密钥的需求

Java

在Java中,如果要使用java.security包中和RSA相关的算法,你需要PKCS#8编码的公私钥,分别使用PKCS8EncodedKeySpecX509EncodedKeySpec加载Base64解码后的数据即可。

如果要使用javax.net.ssl下的KeyStore或者TrustStore,最好使用jks格式,可以省去很多麻烦。

CSharp

在.Net中,System.Security.Cryptography下的X509Certificate2X509Certificate已经过时了)使用p12格式。

一些问题

.Net 证书验证

默认情况下,.Net会对证书做很严格的检验,包括但不限于证书链、吊销情况,SSL/TLS中还会检验主机名。但对于自签名证书,吊销情况是无法通过检查的,因此需要手动把吊销检验关闭:

var chain = new X509Chain();chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;chain.Build(yourCert);

Java 证书验证

Java会自己维护一个证书链(位于JAVA_HOME/lib/security/cacerts),因此把证书加到系统的cacerts里似乎是无效的。对于 SSLContext,必须要自己把证书加到 TrustStore里。需要指出的是,如果使用JSSE,Java是不会验证主机名的,必须自己处理,有讨论。

参考资料


原文链接:

转载地址:http://lfwql.baihongyu.com/

你可能感兴趣的文章
数据结构——栈
查看>>
rocketmq之源码分析源码构建(二)
查看>>
[转载] New Concept English 1——Lesson 2 Is this your...?
查看>>
Java IO_Socket
查看>>
我的友情链接
查看>>
[转载] 七龙珠第一部——第080话 悟空对抗天龙
查看>>
Facebook账号被锁定怎么找回
查看>>
HTTP协议详解
查看>>
Maven学习总结(八)——使用Maven构建多模块项目
查看>>
css之防止出现因浏览器不同出现样式不同的情况
查看>>
MYSQL基本语句
查看>>
我的友情链接
查看>>
一、OkHttp请求方法
查看>>
Linux实用工具
查看>>
Maven学习总结(四)——Maven核心概念
查看>>
Java8 十大新特性详解
查看>>
多线程的同步介绍
查看>>
开源js框架中各种你看不懂的js语法解释大全!!
查看>>
Mysql学习总结(9)——MySql视图原理讲解与使用大全
查看>>
linux挂载ipsan服务器
查看>>