💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
## 一、概述 **X.509**:这是一种证书标准,主要定义了证书中应该包含哪些内容.其详情可以参考RFC5280,SSL使用的就是这种证书标准; **自签名证书和CA签名证书** 自签名的证书无法被吊销,CA签名的证书可以被吊销; ## 二、各种术语 ### **证书编码格式** **PEM**:Privacy Enhanced Mail,是ASCII编码格式; **DER**:Distinguished Encoding Rules,是二进制编码格式,可包含所有私钥、公钥和证书。它是大多数浏览器的缺省格式,并按 ASN1 DER 格式存储。它是无报头的。可以说,PEM 是用文本报头包围的 DER; 两种证书编码可以转换; **PEM转为DER**: ``` openssl x509 -in cert.crt -outform der -out cert.der ``` **DER转为PEM**: ``` openssl x509 -in cert.crt -inform der -outform pem -out cert.pem ``` ### **证书文件后缀** **DER**:DER编码证书; **PEM**:PEM编码证书; **CRT**:常见与Unix/Linux操作系统,有可能是PEM编码,也有可能是DER编码,包含公钥和主体信息,证书中没有私钥,CRT和CER几乎一样; **CER**:常见于Windows系统,同样的,可能是PEM编码,也可能是DER编码,包含公钥和主体信息,证书中没有私钥,Windows下有工具可以转换CRT到CER; **PFX/P12**:包含**公钥**和**私钥**,证书交换格式,后缀为pfx或p12; **JKS**:即Java Key Storage,这是Java的专利,跟OpenSSL关系不大,利用Java的一个叫"keytool"的工具,可以将PFX转为JKS,当然了,keytool也能直接生成JKS; ### **非证书文件后缀** **KEY**:通常用来存放一个公钥或者私钥,并非X.509证书,编码可能是PEM,也可能是DER; **CSR**:Certificate Signing Request,即证书签名请求,这个并不是证书,而是向权威证书颁发机构获得签名证书的申请,其核心内容是一个公钥和主体信息,在生成这个申请的时候,同时也会生成一个私钥文件,需要保存; ### **公钥私钥** 公钥(Public Key)与私钥(Private Key)是通过加密算法得到的一个密钥对(即一个公钥和一个私钥,也就是非对称加密方式)。 公钥可对会话进行加密、验证数字签名,只有使用对应的私钥才能解密会话数据,从而保证数据传输的安全性。公钥是密钥对外公开的部分,私钥则是非公开的部分,由用户自行保管; 通过加密算法得到的密钥对可以保证在世界范围内是唯一的。使用密钥对的时候,如果用其中一个密钥加密一段数据,只能使用密钥对中的另一个密钥才能解密数据。例如:用公钥加密的数据必须用对应的私钥才能解密;如果用私钥进行加密也必须使用对应的公钥才能解密,否则将无法成功解密。 ## 三、keytool工具 openssl和keytool是常用的两个生成证书的工具; ### **概述** jdk自带的证书管理工具叫keytool,可以用来生成自签名证书、导入导出证书、打印证书信息等; keystore和truststore keystore: keytool生成证书的存储库,用来存储若干条目,每一条目包含公私钥,主体信息等;默认为用户目录下.keystore,相当于一个有密码保护的文件; truststore: 与keystore格式相同,但是为区分只用来存放信任的证书,不存密钥等信息; ### **常用命令** -genkey:在用户主目录中创建一个默认文件".keystore",还会产生一个mykey的别名,mykey中包含用户的公钥、私钥和证书; -alias:产生别名; -keystore:生成秘钥库的存储路径和名称; -storepass:指定秘钥库的密码(获取keystore信息所需的密码); -keypass:秘钥口令; -keyalg:指定密钥的算法 (如 RSA DSA(如果不指定默认采用DSA)); -validity:指定创建的证书有效期多少天; -keysize:指定密钥长度; -dname:指定证书拥有者信息 例如: "CN=名字与姓氏,OU=组织单位名称,O=组织名称,L=城市或区域名称,ST=州或省份名称,C=单位的两字母国家代码"; -export:将别名指定的证书导出到文件; -file:参数指定导出到文件的文件名; ## 四、openssl制作 使用openssl来制作证书; ### **CA** ``` openssl req -newkey rsa:2048 -x509 -nodes -sha256 -days 36500 -extensions v3_ca -keyout ca.key -out ca.crt ``` 输入相关信息,生成ca.crt证书和ca.key; ![](https://img.kancloud.cn/20/8a/208a9ef57e3c70807e6bd141da877290_1051x335.png) >[danger] 注意,后面服务器端证书和客户端证书都是用这个相同的ca.crt来制作的; ### **服务器端** 生成服务器端的key; ``` openssl genrsa -des3 -out server.key 2048 ``` 输入密码,如rayframework,生成server.key; ![](https://img.kancloud.cn/40/9c/409c5787283596f3b6fee859b36235b6_1045x122.png) 生成服务器端待发送的CSR; ``` openssl req -out server.csr -key server.key -new ``` 输入刚才生成server.key的密码,如rayframework,以及组织信息等,然后challenge密码可以不要填写,生成待发送CA的server的CSR; ![](https://img.kancloud.cn/4c/b5/4cb59fe0849aafb38e6e7dd5280e1fd4_1050x338.png) 发送CSR到CA用CA的key来签名,生成服务器端证书: ``` openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 36500 ``` 执行后,生成server.crt了; ![](https://img.kancloud.cn/6f/cd/6fcdd168abcf2aa7ec34ebeb75da0ecb_1052x95.png) ### **客户端** 生成客户端key; ``` openssl genrsa -des3 -out client.key 2048 ``` 输入客户端密码,如rayframework,生成client.key; ![](https://img.kancloud.cn/70/4e/704e6440d614960cc4a2bfdefb316e0a_1057x125.png) 生成客户端CSR; ``` openssl req -out client.csr -key client.key -new ``` 输入刚才生成client.key的密码,如rayframework,以及组织信息等,然后challenge密码可以不要填写,生成待发送CA的client的CSR; ![](https://img.kancloud.cn/4b/27/4b274e72dedfd484583e24d6c1be4b8b_1046x334.png) 发送CSR到CA用CA的key来签名,生成客户端证书: ``` openssl x509 -req -in client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out client.crt -days 36500 ``` 执行后,生成client.crt了; ![](https://img.kancloud.cn/41/17/4117af82371b2d1a28ccf22ed9944f71_1052x97.png) ## 五、常见问题 ### **解决服务器启动每次都要输入Enter PEM pass phrase** 把服务器端的key里面的key剥离掉就好了; ``` openssl rsa -in server.key -out server.key.unsecure mv server.key.unsecure server.key ```