Blog Archives

用R语言配合openssl命令行生成和管理x509证书

R的极客理想系列文章,涵盖了R的思想,使用,工具,创新等的一系列要点,以我个人的学习和体验去诠释R的强大。

R语言作为统计学一门语言,一直在小众领域闪耀着光芒。直到大数据的爆发,R语言变成了一门炙手可热的数据分析的利器。随着越来越多的工程背景的人的加入,R语言的社区在迅速扩大成长。现在已不仅仅是统计领域,教育,银行,电商,互联网….都在使用R语言。

要成为有理想的极客,我们不能停留在语法上,要掌握牢固的数学,概率,统计知识,同时还要有创新精神,把R语言发挥到各个领域。让我们一起动起来吧,开始R的极客理想。

关于作者:

  • 张丹,分析师/程序员/Quant: R,Java,Nodejs
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

转载请注明出处:
http://blog.fens.me/r-crypto-openssl-cert/

前言

openssl工具博大精深,本文尝试了使用 openssl 的命令行工具结合R语言中的openssl包的工具,进行了秘钥生成,证书生成,证书管理,证书下载,证书验证等的功能尝试,对秘钥和x509证书进行生成、管理和应用。本文为openssl的第三篇文章,R语言配合openssl生成管理应用x509证书。

由于最近对密码学产生兴趣,使用R语言做一个密码学的研究,因此对R语言中openssl包进行了研究,openssl的文章分别是,R语言进行非对称加密RSAR语言进行AES对称加密R语言配合openssl生成管理应用x509证书用R语言实现RSA+AES混合加密

加密算法涉及到密码学的很多深入的知识,我并没有深入研究,本文只针对于openssl的使用,如果有任何与专业教材不符合的描述,请以专业教材为准。

目录

  1. X.509证书的基本知识
  2. 用 openssl 命令工具生成证书
  3. 用 R语言进行证书管理
  4. 获取网站证书并验证

1. X.509证书的基本知识

在互联网应用中,为保证服务器端和客户端的相互信息、数据安全等的要求,做大量使用到证书用来确认双方身份。X.509证书主要用于识别互联网通信和计算机网络中的身份,保护数据传输安全。

X.509证书的结构优势在于它是由公钥和私钥组成的密钥对而构建的。公钥和私钥能够用于加密和解密信息,验证发送者的身份和确保消息本身的安全性。基于X.509的PKI最常见的用例是使用SSL证书让网站与用户之间实现HTTPS安全浏览。X.509协议同样也适用于应用程序安全的代码签名、数字签名和其他重要的互联网协议。

证书文件的常用的扩展名和秘钥扩展名。

  • .crt .cer .der,证书文件(Certificate),通常是DER二进制格式的
  • .pem,der编码的证书再进行Base64编码的数据存放在”—–BEGIN CERTIFICATE—–“和”—–END CERTIFICATE—–“之中
  • .key,密钥文件,私钥和公钥匙
  • .csr,证书认证签名请求(Certificate signing request)

在本地的window环境中,可以运行 certmgr.msc 来查看本地系统中,所有提前预制的CA机构证书。

2. 用 openssl 命令工具生成证书

我们来模拟一下网站向CA申请证书的互联网应用场景,由于并不是去真实的CA机构申请证书,我们可以把CA机构一起进行模拟。自己设定一个CA机构生成一个CA机构证书,再生成一个自己网站(fens.me)的证书,然后用CA的证书对自己的网站证书进行签名,来模拟一个实际网站申请证书的过程。

我接下来通过命令行openssl工具生成证书。本机环境为window10,通过安装Git工具,使用自带的Mingw64的工具中的openssl环境。


# 查看openssl 版本
dan@DanZhang MINGW64 /c/work/R/encrypt/n1
$ openssl version
OpenSSL 1.1.1d  10 Sep 2019

2.1 生成CA根证书的步骤
我们要生成自签名的证书,所以我们需要自己扮演CA,作为CA颁发证书的机构。

操作步骤:生成CA私钥(ca.key)–>生成自签名得到根证书(.crt)

第一步,生成CA私钥(ca.key),生成CA认证机构的证书密钥key。
使用命令:openssl genrsa -out ca.key 2048
参数:

  • -out ca.key:将生成的私钥保存至ca.key文件。
  • 2048为要生成的私钥的长度。

# 生成CA私钥ca.key
dan@DanZhang MINGW64 /c/work/R/encrypt/n1
$ openssl genrsa -out ca.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
.............................................................................+++++
...............................+++++
e is 65537 (0x010001)

# 查看生成的ca.key的内容
$ cat ca.key
-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA1iLmJeJHYeVutw6Ui+V/tZs2SS4GFzTWRkoRmmt4Z+5jQMt/
dv94WbjmKyvNNrXiNiGz1jZQsw2Bj+22rSKjGEh4Qipjpcc+AOfl99V3diH8YM/c
wj6dNFKqqmpJHtzDSbhOudPbwDsFugq3dyVsV1hMKrlEBetI7Qj/8kZSie1KL+QS
00G+ISCHUes8f/eFHgd7sMXpOb65NJhAKZGSeT49V+IeF1M82VJEyV+x1p/C3ppA
L9PTt3RFftTQJjXW48tIfS3R85E0libyeQnlxM3slEf2UnO16wq/7j3KmWiPD9vm
tPnhNjKbBr6PbtAR+CAsSpxaVLMpA1PDydqsCQIDAQABAoIBAQDKI22QK3do0TTf
NrNBECarH1ZyZDC5rVXsSjUtyO+DZIRrAO5VPbm1MJaOAC4azD07Djt+Jg2tyD0a
ybIc48qDvL1Q8ETalCdSoZXzip3XdSORnAZvkr3BS5vxfJ2Dta/fok0mm/ggEVdJ
lJ41qa0JEr/rwLGWyNExeMJrSLjXmt4S3fkZNJ12icCRKddeFyTL17LEf6lENXol
e/SWuvB1+RhZb73eJVMPTJcoRXulJ0/pUD2QxLMn/YhvMVH8A13v9TipmS51mwLP
FN8F9BNm2K6QXHgQLghjYbpDk1pRTzj+4Yr6dbWZipHSWWJy1WKMm93M+5VNuG6a
tKGj/HQ1AoGBAPhhIxczFZxhd4qs6t09OkU2aEpGYcdMGEYFd7OUYhjUOhXHUMMC
uUWAq2555VaUrKhlqovp+uTdMESop7Ac6gfSH0yG1rTLSiFCuOsNcBx1FKUgCh3Q
OP0JugH6yOJuCwyT1DCoipGbq/sjhaUmb+sqwN+IhcQ6vCw4Qnp2emvfAoGBANy0
zdG7PIL2i9Rub38+cR0/rFdZJFqWQXv/j1c+o+cAQfzsk6jPV5uR+St+HXyafMNu
I7po1mvp7v1UJceFrynZGqdS0FNALmDAnySaPoyhqSjk+nB88MkSEcACr64Smumw
5DHkU3hO+hhayCzPIsILiU67jXvIP3F5GabxNGUXAoGAGN+JZxJbkKyGDyIf5wXx
puq66O1Bb3bkW2bCxP4QENJ3+qRaJx1HtnkbMdYNLG15GOgNezN0R6UK52VIXa+X
lC7rqXs7VyGgi9IluIxA9OiYp6yctr2aZ2So9vfJVDuW6ayILFNEhS5ku6KkCJTf
0loWtIv0cWE8ZOVBawggXFsCgYBWw612Ggl74rit1ox2lXGacgGqhRzJj/BGcv1C
6xk8ItnOOKMD5h8mxYgTFQ06gvExUwcwrS4+VkThykbf3SozZWoZBXFoiP6ygocN
uKWGW7dIoFvkBPoT0cqwlV3DLQVBgYz0IDLARSwEjwvKsdOUPTzJeunwE5T9YwI2
ovRaGQKBgF0zysxImSvnC8jQFB5+jw5dCnP8gXDljZPDJhxwlkbNc85ikA27vSkQ
+ql0YOsgka3DH4ISOpMGJXaCTkI86OXtLlG0HBjLgiiyYQnFieQ1xPB3PfCPKWHl
G84TmLUw9uxC08jV0r7UfIDBxv7kNGDLJqyTmsCYON9EXbbt03ac
-----END RSA PRIVATE KEY-----

第二步,生成自签名得到根证书(ca.crt),CA的基本信息,生成证书时填入的信息,包含国家,地区,公司,域名等信息。
使用命令:openssl req -new -x509 -key ca.key -out ca.crt -days 365
参数说明:

  • -new :说明生成证书请求文件
  • -x509 :说明生成自签名证书
  • -key :指定已有的秘钥文件生成秘钥请求,只与生成证书请求选项-new配合。
  • -days:证书有效天数
  • -out :-out 指定生成的证书请求或者自签名证书名称

# 自签名得到根证书(.crt)
dan@DanZhang MINGW64 /c/work/R/encrypt/n1
$  openssl req -new -x509 -key ca.key -out ca.crt -days 365
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) [AU]:ZH
State or Province Name (full name) [Some-State]:BJ
Locality Name (eg, city) []:BEIJING
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:
Common Name (e.g. server FQDN or YOUR name) []:myca.com
Email Address []:bsspirit@gmail.com

2.2 生成用户证书的步骤
接下来,生成我自己的博客的 fens.me 网站的秘钥,然后生成证书请求,用CA的证书进行签名,最后自己网站的证书。。

生成私钥(.key)–>生成证书请求(.csr)–>用CA根证书签名得到证书(.crt)

第一步,生成私钥(fens.me.key)


dan@DanZhang MINGW64 /c/work/R/encrypt/n1
$ openssl genrsa -out fens.me.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
...............................................................................................................+++++
.................................+++++
e is 65537 (0x010001)

第二步,生成CSR(Certificate Signing Request)证书请求(fens.me.csr)


dan@DanZhang MINGW64 /c/work/R/encrypt/n1
$ openssl req -new -key fens.me.key -out fens.me.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) [AU]:ZH
State or Province Name (full name) [Some-State]:BJ
Locality Name (eg, city) []:BEIJING
Organization Name (eg, company) [Internet Widgits Pty Ltd]:
Organizational Unit Name (eg, section) []:fens.me
Common Name (e.g. server FQDN or YOUR name) []:
Email Address []:bsspirit@gmail.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:fens.me
An optional company name []:

查看CSR文件中的信息,需要用到openssl命令工具来查看


dan@DanZhang MINGW64 /c/work/R/encrypt/n1
$ openssl req -text -noout -verify -in fens.me.csr
Certificate Request:
    Data:
        Version: 1 (0x0)
        Subject: C = ZH, ST = BJ, L = BEIJING, O = Internet Widgits Pty Ltd, OU = fens.me, emailAddress = bsspirit@gmail.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:b5:d3:98:e5:0f:57:19:a0:dd:c1:aa:7d:de:55:
                    c7:e7:ae:dc:03:30:68:f8:71:32:8b:c2:14:d8:b3:
                    31:ec:55:ca:70:fb:e2:17:8b:86:8f:c6:10:4e:fb:
                    4f:25:80:cf:9b:cf:6d:46:b6:ba:90:8f:a1:68:ba:
                    c2:ef:c4:99:e2:8a:0b:7f:af:7b:37:d7:5c:5a:5f:
                    0c:10:b3:3a:ab:b1:a6:c0:9d:8a:42:42:68:0c:c3:
                    07:52:b3:39:c1:8e:9f:dc:7b:c5:88:11:9d:7f:cd:
                    ad:95:27:42:47:a8:af:74:dc:66:df:d7:29:0b:ae:
                    3c:f6:4a:d2:dc:6b:20:60:5d:59:37:55:c0:48:68:
                    40:31:67:b5:d6:68:13:ed:f1:b2:70:00:7f:b0:c5:
                    1a:ba:e3:f5:c4:42:97:ef:1b:68:3c:43:ff:dc:81:
                    0d:7a:6f:f4:88:60:ce:47:32:7b:64:27:a0:e7:89:
                    e7:fa:60:73:6a:64:77:34:d9:6b:2a:f5:9b:c4:6f:
                    49:82:84:43:01:8a:ea:90:d6:0b:5c:f1:19:9f:56:
                    c2:c1:df:22:29:28:79:40:5f:72:13:ac:9b:b0:6f:
                    0b:b6:09:9f:c4:a8:12:5d:51:16:f0:81:e2:41:6a:
                    2a:74:56:bf:48:77:26:84:f9:57:f3:f9:f4:af:94:
                    68:bd
                Exponent: 65537 (0x10001)
        Attributes:
            challengePassword        :fens.me
    Signature Algorithm: sha256WithRSAEncryption
         10:cf:2f:82:24:a5:48:b0:c9:c2:79:00:eb:ba:70:8f:02:f4:
         cb:7a:b8:9b:d9:eb:9c:dd:34:03:9e:d7:3a:bd:7d:08:af:11:
         2c:a5:3e:0b:40:8c:3e:64:bb:c6:8b:b0:b0:6a:cb:59:b9:9b:
         e1:a1:d9:bc:ec:10:ed:d8:29:f2:a3:fd:f1:94:c6:4e:26:95:
         23:25:28:b7:01:fa:3d:bd:96:8b:b5:e8:f4:6b:c3:b9:67:a9:
         29:27:96:18:51:98:3a:45:87:31:35:6c:16:51:be:60:40:6e:
         2d:ea:0d:d6:0c:36:6f:5d:24:4e:c1:20:f7:42:7b:9e:62:81:
         e6:38:88:03:0a:7e:15:01:8e:ab:ac:9b:30:93:21:72:19:bf:
         9d:4d:51:ba:30:74:34:4f:1b:30:4d:c8:74:ca:e8:3e:15:a5:
         ec:2c:0e:79:4f:d1:11:56:0f:da:38:d0:6b:1e:54:ac:50:28:
         04:d2:8d:b4:6b:f3:d1:ee:a5:f2:43:6f:4c:73:42:13:df:66:
         30:4f:6c:16:6f:99:91:9f:56:ec:c2:99:aa:e1:82:28:2a:ce:
         e2:4e:9e:95:c4:52:fa:be:7a:8e:1e:32:6f:f9:83:92:c1:8a:
         da:a8:a1:ef:e6:df:14:bb:16:c0:b9:67:8d:71:43:69:d4:2e:
         2d:6a:9d:4c
verify OK

第三步,用CA根证书签名得到证书。实际过程中,会把上面生成的fens.me.csrR文件发给CA,请求CA签名,从而生成网站证书 fens.me.crt。


dan@DanZhang MINGW64 /c/work/R/encrypt/n1
$ openssl x509 -req -in fens.me.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out fens.me.crt -days 365
Signature ok
subject=C = ZH, ST = BJ, L = BEIJING, O = Internet Widgits Pty Ltd, OU = fens.me, emailAddress = bsspirit@gmail.com
Getting CA Private Key

# 查看证书中的内容
$ openssl x509 -in fens.me.crt -text -noout
Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number: 1 (0x1)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = ZH, ST = BJ, L = BEIJING, O = Internet Widgits Pty Ltd, CN = myca.com, emailAddress = bsspirit@gmail.com
        Validity
            Not Before: Nov 30 09:47:58 2022 GMT
            Not After : Nov 30 09:47:58 2023 GMT
        Subject: C = ZH, ST = BJ, L = BEIJING, O = Internet Widgits Pty Ltd, OU = fens.me, emailAddress = bsspirit@gmail.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (2048 bit)
                Modulus:
                    00:b5:d3:98:e5:0f:57:19:a0:dd:c1:aa:7d:de:55:
                    c7:e7:ae:dc:03:30:68:f8:71:32:8b:c2:14:d8:b3:
                    31:ec:55:ca:70:fb:e2:17:8b:86:8f:c6:10:4e:fb:
                    4f:25:80:cf:9b:cf:6d:46:b6:ba:90:8f:a1:68:ba:
                    c2:ef:c4:99:e2:8a:0b:7f:af:7b:37:d7:5c:5a:5f:
                    0c:10:b3:3a:ab:b1:a6:c0:9d:8a:42:42:68:0c:c3:
                    07:52:b3:39:c1:8e:9f:dc:7b:c5:88:11:9d:7f:cd:
                    ad:95:27:42:47:a8:af:74:dc:66:df:d7:29:0b:ae:
                    3c:f6:4a:d2:dc:6b:20:60:5d:59:37:55:c0:48:68:
                    40:31:67:b5:d6:68:13:ed:f1:b2:70:00:7f:b0:c5:
                    1a:ba:e3:f5:c4:42:97:ef:1b:68:3c:43:ff:dc:81:
                    0d:7a:6f:f4:88:60:ce:47:32:7b:64:27:a0:e7:89:
                    e7:fa:60:73:6a:64:77:34:d9:6b:2a:f5:9b:c4:6f:
                    49:82:84:43:01:8a:ea:90:d6:0b:5c:f1:19:9f:56:
                    c2:c1:df:22:29:28:79:40:5f:72:13:ac:9b:b0:6f:
                    0b:b6:09:9f:c4:a8:12:5d:51:16:f0:81:e2:41:6a:
                    2a:74:56:bf:48:77:26:84:f9:57:f3:f9:f4:af:94:
                    68:bd
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
         7d:5e:a2:f1:c4:91:19:4f:c3:6a:88:7c:33:4b:d8:fc:20:e3:
         e4:ad:38:23:5e:90:95:46:fe:4a:45:4d:70:58:2a:90:c2:b9:
         53:a4:80:90:b4:6d:a5:b9:c0:b0:73:8c:ff:9d:f2:b4:06:93:
         da:66:67:e2:85:0e:9b:11:64:70:c5:b6:a2:93:8b:3e:00:cb:
         1c:34:0c:3a:34:86:16:8b:7a:c6:e4:6a:8e:4f:cb:86:ea:25:
         1d:dc:18:1b:c4:74:b0:a5:d1:a4:e7:f6:f4:e8:44:c4:13:e0:
         a5:b5:3f:c5:54:ae:f3:e4:ee:9a:53:6a:53:73:e3:84:df:65:
         ac:93:de:94:46:9a:4b:2f:7f:d4:cb:b9:de:ac:9b:72:9b:68:
         f4:bf:59:e8:79:b0:c5:cd:2a:7c:70:d1:ff:2b:3c:10:0a:8b:
         d4:36:33:68:d4:d7:1f:0e:16:98:f6:10:eb:a5:23:a8:22:9f:
         66:f5:0a:b0:1b:05:54:ab:4c:08:cf:55:c2:46:13:de:b0:e7:
         2c:76:6a:3d:5f:ec:44:f0:9c:75:d6:13:ca:d1:20:02:7c:9c:
         ea:48:58:aa:e2:15:02:37:a3:07:f9:40:89:4e:ba:2a:02:19:
         a3:e7:9f:65:00:d5:e1:27:dd:63:50:74:30:b8:7b:8b:4b:95:
         93:f2:ec:b1

查看当前目录中的文件,共5个


dan@DanZhang MINGW64 /c/work/R/encrypt/n1
$ ll
total 20
-rw-r--r-- 1 dan 197121 1448 Nov 30 17:40 ca.crt
-rw-r--r-- 1 dan 197121 1702 Nov 30 15:26 ca.key
-rw-r--r-- 1 dan 197121 1294 Nov 30 17:47 fens.me.crt
-rw-r--r-- 1 dan 197121 1096 Nov 30 17:45 fens.me.csr
-rw-r--r-- 1 dan 197121 1702 Nov 30 17:44 fens.me.key

2.3 查看证书
用windows程序打开证书,左边是  fens.me.crt证书,右边为ca.crt根证书。

  • ca.crt根证书,是我们自己的生成的,未获得电脑的信任。通过安装ca.crt根证书,让本机电脑获得信任。
  • fens.me.crt证书,用ca.crt根证书颁发的。

这样我们就完成了,就openssl命令行工具生成自制证书的过程,一路下来还是挺顺利的。

3. 用 R语言进行证书管理

本来我是打算用R语言openssl包,重现上面的证书生成的过程,但查了很多资料发现在R中,并没有用于证书生成的函数支持,只能做证书的一些管理和验证。那么,我就把openssl包中,能有关证书支持的函数,做一个介绍。

证书相关的函数:

  • read_cert,读取证书文件
  • read_cert_bundle,读取证书包
  • read_pem,以pem格式,读证书
  • read_pubkey,读取公钥
  • write_pem,以pem格式,输出秘钥和证书
  • write_pkcs1,以pkcs格式,输出秘钥和证书
  • write_ssh,以ssh格式,输出秘钥和证书
  • ca_bundle,X509证书集合
  • certificates,证书检查
  • cert_verify,证书验证

我们用R语言API来读取刚才生成ca.key秘钥查看秘钥的信息,并比较确认生成key的秘钥格式。

3.1 取读ca.key的私钥
使用read_key() 以私钥方式进行读取。


# 以私钥方式进行读取                             
> cakey<-read_key("./ca.key");cakey
[2048-bit rsa private key]
md5: 87be025db1f33785aafa00aa83388a8b
sha256: c03bc0d35b4593ff81cde4545b1aa62f80e754545297f30669bdcce29a910a45

# 查看cakey结构
> str(cakey)
List of 4
 $ type  : chr "rsa"
 $ size  : int 2048
 $ pubkey:List of 5
  ..$ type       : chr "rsa"
  ..$ size       : int 2048
  ..$ ssh        : chr "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWIuYl4kdh5 ..."
  ..$ fingerprint: 'hash' raw [1:32] c0 3b c0 d3 ...
  ..$ data       :List of 2
  .. ..$ e: 'bignum' raw [1:3] 01 00 01
  .. ..$ n: 'bignum' raw [1:257] 00 d6 22 e6 ...
 $ data  :List of 8
  ..$ e : 'bignum' raw [1:3] 01 00 01
  ..$ n : 'bignum' raw [1:257] 00 d6 22 e6 ...
  ..$ p : 'bignum' raw [1:129] 00 f8 61 23 ...
  ..$ q : 'bignum' raw [1:129] 00 dc b4 cd ...
  ..$ d : 'bignum' raw [1:257] 00 ca 23 6d ...
  ..$ dp: 'bignum' raw [1:128] 18 df 89 67 ...
  ..$ dq: 'bignum' raw [1:128] 56 c3 ad 76 ...
  ..$ qi: 'bignum' raw [1:128] 5d 33 ca cc ...

# 查看ssh格式
> ca.ssh<-write_ssh(cakey);ca.ssh
[1] "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDWIuYl4kdh5W63DpSL5X+1mzZJLgYXNNZGShGaa3hn7mNAy392/3hZuOYrK802teI2IbPWNlCzDYGP7batIqMYSHhCKmOlxz4A5+X31Xd2Ifxgz9zCPp00Uqqqakke3MNJuE6509vAOwW6Crd3JWxXWEwquUQF60jtCP/yRlKJ7Uov5BLTQb4hIIdR6zx/94UeB3uwxek5vrk0mEApkZJ5Pj1X4h4XUzzZUkTJX7HWn8LemkAv09O3dEV+1NAmNdbjy0h9LdHzkTSWJvJ5CeXEzeyUR/ZSc7XrCr/uPcqZaI8P2+a0+eE2MpsGvo9u0BH4ICxKnFpUsykDU8PJ2qwJ"

# 查看der格式
> ca.der<-write_der(cakey);ca.der
   [1] 30 82 04 a3 02 01 00 02 82 01 01 00 d6 22 e6 25 e2 47 61 e5 6e b7 0e 94
  [25] 8b e5 7f b5 9b 36 49 2e 06 17 34 d6 46 4a 11 9a 6b 78 67 ee 63 40 cb 7f
  [49] 76 ff 78 59 b8 e6 2b 2b cd 36 b5 e2 36 21 b3 d6 36 50 b3 0d 81 8f ed b6
  [73] ad 22 a3 18 48 78 42 2a 63 a5 c7 3e 00 e7 e5 f7 d5 77 76 21 fc 60 cf dc
  [97] c2 3e 9d 34 52 aa aa 6a 49 1e dc c3 49 b8 4e b9 d3 db c0 3b 05 ba 0a b7
 [121] 77 25 6c 57 58 4c 2a b9 44 05 eb 48 ed 08 ff f2 46 52 89 ed 4a 2f e4 12
 [145] d3 41 be 21 20 87 51 eb 3c 7f f7 85 1e 07 7b b0 c5 e9 39 be b9 34 98 40
 [169] 29 91 92 79 3e 3d 57 e2 1e 17 53 3c d9 52 44 c9 5f b1 d6 9f c2 de 9a 40
 [193] 2f d3 d3 b7 74 45 7e d4 d0 26 35 d6 e3 cb 48 7d 2d d1 f3 91 34 96 26 f2
 [217] 79 09 e5 c4 cd ec 94 47 f6 52 73 b5 eb 0a bf ee 3d ca 99 68 8f 0f db e6
 [241] b4 f9 e1 36 32 9b 06 be 8f 6e d0 11 f8 20 2c 4a 9c 5a 54 b3 29 03 53 c3
 [265] c9 da ac 09 02 03 01 00 01 02 82 01 01 00 ca 23 6d 90 2b 77 68 d1 34 df
 [289] 36 b3 41 10 26 ab 1f 56 72 64 30 b9 ad 55 ec 4a 35 2d c8 ef 83 64 84 6b
 [313] 00 ee 55 3d b9 b5 30 96 8e 00 2e 1a cc 3d 3b 0e 3b 7e 26 0d ad c8 3d 1a
 [337] c9 b2 1c e3 ca 83 bc bd 50 f0 44 da 94 27 52 a1 95 f3 8a 9d d7 75 23 91
 [361] 9c 06 6f 92 bd c1 4b 9b f1 7c 9d 83 b5 af df a2 4d 26 9b f8 20 11 57 49
 [385] 94 9e 35 a9 ad 09 12 bf eb c0 b1 96 c8 d1 31 78 c2 6b 48 b8 d7 9a de 12
 [409] dd f9 19 34 9d 76 89 c0 91 29 d7 5e 17 24 cb d7 b2 c4 7f a9 44 35 7a 25
 [433] 7b f4 96 ba f0 75 f9 18 59 6f bd de 25 53 0f 4c 97 28 45 7b a5 27 4f e9
 [457] 50 3d 90 c4 b3 27 fd 88 6f 31 51 fc 03 5d ef f5 38 a9 99 2e 75 9b 02 cf
 [481] 14 df 05 f4 13 66 d8 ae 90 5c 78 10 2e 08 63 61 ba 43 93 5a 51 4f 38 fe
 [505] e1 8a fa 75 b5 99 8a 91 d2 59 62 72 d5 62 8c 9b dd cc fb 95 4d b8 6e 9a
 [529] b4 a1 a3 fc 74 35 02 81 81 00 f8 61 23 17 33 15 9c 61 77 8a ac ea dd 3d
 [553] 3a 45 36 68 4a 46 61 c7 4c 18 46 05 77 b3 94 62 18 d4 3a 15 c7 50 c3 02
 [577] b9 45 80 ab 6e 79 e5 56 94 ac a8 65 aa 8b e9 fa e4 dd 30 44 a8 a7 b0 1c
 [601] ea 07 d2 1f 4c 86 d6 b4 cb 4a 21 42 b8 eb 0d 70 1c 75 14 a5 20 0a 1d d0
 [625] 38 fd 09 ba 01 fa c8 e2 6e 0b 0c 93 d4 30 a8 8a 91 9b ab fb 23 85 a5 26
 [649] 6f eb 2a c0 df 88 85 c4 3a bc 2c 38 42 7a 76 7a 6b df 02 81 81 00 dc b4
 [673] cd d1 bb 3c 82 f6 8b d4 6e 6f 7f 3e 71 1d 3f ac 57 59 24 5a 96 41 7b ff
 [697] 8f 57 3e a3 e7 00 41 fc ec 93 a8 cf 57 9b 91 f9 2b 7e 1d 7c 9a 7c c3 6e
 [721] 23 ba 68 d6 6b e9 ee fd 54 25 c7 85 af 29 d9 1a a7 52 d0 53 40 2e 60 c0
 [745] 9f 24 9a 3e 8c a1 a9 28 e4 fa 70 7c f0 c9 12 11 c0 02 af ae 12 9a e9 b0
 [769] e4 31 e4 53 78 4e fa 18 5a c8 2c cf 22 c2 0b 89 4e bb 8d 7b c8 3f 71 79
 [793] 19 a6 f1 34 65 17 02 81 80 18 df 89 67 12 5b 90 ac 86 0f 22 1f e7 05 f1
 [817] a6 ea ba e8 ed 41 6f 76 e4 5b 66 c2 c4 fe 10 10 d2 77 fa a4 5a 27 1d 47
 [841] b6 79 1b 31 d6 0d 2c 6d 79 18 e8 0d 7b 33 74 47 a5 0a e7 65 48 5d af 97
 [865] 94 2e eb a9 7b 3b 57 21 a0 8b d2 25 b8 8c 40 f4 e8 98 a7 ac 9c b6 bd 9a
 [889] 67 64 a8 f6 f7 c9 54 3b 96 e9 ac 88 2c 53 44 85 2e 64 bb a2 a4 08 94 df
 [913] d2 5a 16 b4 8b f4 71 61 3c 64 e5 41 6b 08 20 5c 5b 02 81 80 56 c3 ad 76
 [937] 1a 09 7b e2 b8 ad d6 8c 76 95 71 9a 72 01 aa 85 1c c9 8f f0 46 72 fd 42
 [961] eb 19 3c 22 d9 ce 38 a3 03 e6 1f 26 c5 88 13 15 0d 3a 82 f1 31 53 07 30
 [985] ad 2e 3e 56 44 e1 ca 46 df dd 2a 33 65 6a 19 05
 [ reached getOption("max.print") -- omitted 191 entries ]

# 查看pkcs1格式
> ca.pkcs1<-write_pkcs1(cakey);ca.pkcs1
[1] "-----BEGIN RSA PRIVATE KEY-----\nMIIEowIBAAKCAQEA1iLmJeJHYeVutw6Ui+V/tZs2SS4GFzTWRkoRmmt4Z+5jQMt/\ndv94WbjmKyvNNrXiNiGz1jZQsw2Bj+22rSKjGEh4Qipjpcc+AOfl99V3diH8YM/c\nwj6dNFKqqmpJHtzDSbhOudPbwDsFugq3dyVsV1hMKrlEBetI7Qj/8kZSie1KL+QS\n00G+ISCHUes8f/eFHgd7sMXpOb65NJhAKZGSeT49V+IeF1M82VJEyV+x1p/C3ppA\nL9PTt3RFftTQJjXW48tIfS3R85E0libyeQnlxM3slEf2UnO16wq/7j3KmWiPD9vm\ntPnhNjKbBr6PbtAR+CAsSpxaVLMpA1PDydqsCQIDAQABAoIBAQDKI22QK3do0TTf\nNrNBECarH1ZyZDC5rVXsSjUtyO+DZIRrAO5VPbm1MJaOAC4azD07Djt+Jg2tyD0a\nybIc48qDvL1Q8ETalCdSoZXzip3XdSORnAZvkr3BS5vxfJ2Dta/fok0mm/ggEVdJ\nlJ41qa0JEr/rwLGWyNExeMJrSLjXmt4S3fkZNJ12icCRKddeFyTL17LEf6lENXol\ne/SWuvB1+RhZb73eJVMPTJcoRXulJ0/pUD2QxLMn/YhvMVH8A13v9TipmS51mwLP\nFN8F9BNm2K6QXHgQLghjYbpDk1pRTzj+4Yr6dbWZipHSWWJy1WKMm93M+5VNuG6a\ntKGj/HQ1AoGBAPhhIxczFZxhd4qs6t09OkU2aEpGYcdMGEYFd7OUYhjUOhXHUMMC\nuUWAq2555VaUrKhlqovp+uTdMESop7Ac6gfSH0yG1rTLSiFCuOsNcBx1FKUgCh3Q\nOP0JugH6yOJuCwyT1DCoipGbq/sjhaUmb+sqwN+IhcQ6vCw4Qnp2emvfAoGBANy0\nzdG7PIL2i9Rub38+cR0/rFdZJFqWQXv/j1c+o+cAQfzsk6jPV5uR+St+HXyafMNu\nI7po1mvp7v1UJceFrynZGqdS0FNALmDAnySaPoyhqSjk+nB88MkSEcACr64Smumw\n5DHkU3hO+hhayCzPIsILiU67jXvIP3F5GabxNGUXAoGAGN+JZxJbkKyGDyIf5wXx\npuq66O1Bb3bkW2bCxP4QENJ3+qRaJx1HtnkbMdYNLG15GOgNezN0R6UK52VIXa+X\nlC7rqXs7VyGgi9IluIxA9OiYp6yctr2aZ2So9vfJVDuW6ayILFNEhS5ku6KkCJTf\n0loWtIv0cWE8ZOVBawggXFsCgYBWw612Ggl74rit1ox2lXGacgGqhRzJj/BGcv1C\n6xk8ItnOOKMD5h8mxYgTFQ06gvExUwcwrS4+VkThykbf3SozZWoZBXFoiP6ygocN\nuKWGW7dIoFvkBPoT0cqwlV3DLQVBgYz0IDLARSwEjwvKsdOUPTzJeunwE5T9YwI2\novRaGQKBgF0zysxImSvnC8jQFB5+jw5dCnP8gXDljZPDJhxwlkbNc85ikA27vSkQ\n+ql0YOsgka3DH4ISOpMGJXaCTkI86OXtLlG0HBjLgiiyYQnFieQ1xPB3PfCPKWHl\nG84TmLUw9uxC08jV0r7UfIDBxv7kNGDLJqyTmsCYON9EXbbt03ac\n-----END RSA PRIVATE KEY-----\n"

# 查看PEM格式
> ca.pem<-write_pem(cakey);ca.pem
[1] "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDWIuYl4kdh5W63\nDpSL5X+1mzZJLgYXNNZGShGaa3hn7mNAy392/3hZuOYrK802teI2IbPWNlCzDYGP\n7batIqMYSHhCKmOlxz4A5+X31Xd2Ifxgz9zCPp00Uqqqakke3MNJuE6509vAOwW6\nCrd3JWxXWEwquUQF60jtCP/yRlKJ7Uov5BLTQb4hIIdR6zx/94UeB3uwxek5vrk0\nmEApkZJ5Pj1X4h4XUzzZUkTJX7HWn8LemkAv09O3dEV+1NAmNdbjy0h9LdHzkTSW\nJvJ5CeXEzeyUR/ZSc7XrCr/uPcqZaI8P2+a0+eE2MpsGvo9u0BH4ICxKnFpUsykD\nU8PJ2qwJAgMBAAECggEBAMojbZArd2jRNN82s0EQJqsfVnJkMLmtVexKNS3I74Nk\nhGsA7lU9ubUwlo4ALhrMPTsOO34mDa3IPRrJshzjyoO8vVDwRNqUJ1KhlfOKndd1\nI5GcBm+SvcFLm/F8nYO1r9+iTSab+CARV0mUnjWprQkSv+vAsZbI0TF4wmtIuNea\n3hLd+Rk0nXaJwJEp114XJMvXssR/qUQ1eiV79Ja68HX5GFlvvd4lUw9MlyhFe6Un\nT+lQPZDEsyf9iG8xUfwDXe/1OKmZLnWbAs8U3wX0E2bYrpBceBAuCGNhukOTWlFP\nOP7hivp1tZmKkdJZYnLVYoyb3cz7lU24bpq0oaP8dDUCgYEA+GEjFzMVnGF3iqzq\n3T06RTZoSkZhx0wYRgV3s5RiGNQ6FcdQwwK5RYCrbnnlVpSsqGWqi+n65N0wRKin\nsBzqB9IfTIbWtMtKIUK46w1wHHUUpSAKHdA4/Qm6AfrI4m4LDJPUMKiKkZur+yOF\npSZv6yrA34iFxDq8LDhCenZ6a98CgYEA3LTN0bs8gvaL1G5vfz5xHT+sV1kkWpZB\ne/+PVz6j5wBB/OyTqM9Xm5H5K34dfJp8w24jumjWa+nu/VQlx4WvKdkap1LQU0Au\nYMCfJJo+jKGpKOT6cHzwyRIRwAKvrhKa6bDkMeRTeE76GFrILM8iwguJTruNe8g/\ncXkZpvE0ZRcCgYAY34lnEluQrIYPIh/nBfGm6rro7UFvduRbZsLE/hAQ0nf6pFon\nHUe2eRsx1g0sbXkY6A17M3RHpQrnZUhdr5eULuupeztXIaCL0iW4jED06JinrJy2\nvZpnZKj298lUO5bprIgsU0SFLmS7oqQIlN/SWha0i/RxYTxk5UFrCCBcWwKBgFbD\nrXYaCXviuK3WjHaVcZpyAaqFHMmP8EZy/ULrGTwi2c44owPmHybFiBMVDTqC8TFT\nBzCtLj5WROHKRt/dKjNlahkFcWiI/rKChw24pYZbt0igW+QE+hPRyrCVXcMtBUGB\njPQgMsBFLASPC8qx05Q9PMl66fATlP1jAjai9FoZAoGAXTPKzEiZK+cLyNAUHn6P\nDl0Kc/yBcOWNk8MmHHCWRs1zzmKQDbu9KRD6qXRg6yCRrcMfghI6kwYldoJOQjzo\n5e0uUbQcGMuCKLJhCcWJ5DXE8Hc98I8pYeUbzhOYtTD27ELTyNXSvtR8gMHG/uQ0\nYMsmrJOawJg430Rdtu3Tdpw=\n-----END PRIVATE KEY-----\n"

再以纯文本方式进行读取ca.key文件,并与PEM和pkcs1格式进行对比,发现key与pkcs1格式项目,这样就明确了ca.key是用pkcs1格式进行存储的。


# 以纯文本方式进行读取
> ca.txt<-readLines("./ca.key");ca.txt
 [1] "-----BEGIN RSA PRIVATE KEY-----"                                 
 [2] "MIIEowIBAAKCAQEA1iLmJeJHYeVutw6Ui+V/tZs2SS4GFzTWRkoRmmt4Z+5jQMt/"
 [3] "dv94WbjmKyvNNrXiNiGz1jZQsw2Bj+22rSKjGEh4Qipjpcc+AOfl99V3diH8YM/c"
 [4] "wj6dNFKqqmpJHtzDSbhOudPbwDsFugq3dyVsV1hMKrlEBetI7Qj/8kZSie1KL+QS"
 [5] "00G+ISCHUes8f/eFHgd7sMXpOb65NJhAKZGSeT49V+IeF1M82VJEyV+x1p/C3ppA"
 [6] "L9PTt3RFftTQJjXW48tIfS3R85E0libyeQnlxM3slEf2UnO16wq/7j3KmWiPD9vm"
 [7] "tPnhNjKbBr6PbtAR+CAsSpxaVLMpA1PDydqsCQIDAQABAoIBAQDKI22QK3do0TTf"
 [8] "NrNBECarH1ZyZDC5rVXsSjUtyO+DZIRrAO5VPbm1MJaOAC4azD07Djt+Jg2tyD0a"
 [9] "ybIc48qDvL1Q8ETalCdSoZXzip3XdSORnAZvkr3BS5vxfJ2Dta/fok0mm/ggEVdJ"
[10] "lJ41qa0JEr/rwLGWyNExeMJrSLjXmt4S3fkZNJ12icCRKddeFyTL17LEf6lENXol"
[11] "e/SWuvB1+RhZb73eJVMPTJcoRXulJ0/pUD2QxLMn/YhvMVH8A13v9TipmS51mwLP"
[12] "FN8F9BNm2K6QXHgQLghjYbpDk1pRTzj+4Yr6dbWZipHSWWJy1WKMm93M+5VNuG6a"
[13] "tKGj/HQ1AoGBAPhhIxczFZxhd4qs6t09OkU2aEpGYcdMGEYFd7OUYhjUOhXHUMMC"
[14] "uUWAq2555VaUrKhlqovp+uTdMESop7Ac6gfSH0yG1rTLSiFCuOsNcBx1FKUgCh3Q"
[15] "OP0JugH6yOJuCwyT1DCoipGbq/sjhaUmb+sqwN+IhcQ6vCw4Qnp2emvfAoGBANy0"
[16] "zdG7PIL2i9Rub38+cR0/rFdZJFqWQXv/j1c+o+cAQfzsk6jPV5uR+St+HXyafMNu"
[17] "I7po1mvp7v1UJceFrynZGqdS0FNALmDAnySaPoyhqSjk+nB88MkSEcACr64Smumw"
[18] "5DHkU3hO+hhayCzPIsILiU67jXvIP3F5GabxNGUXAoGAGN+JZxJbkKyGDyIf5wXx"
[19] "puq66O1Bb3bkW2bCxP4QENJ3+qRaJx1HtnkbMdYNLG15GOgNezN0R6UK52VIXa+X"
[20] "lC7rqXs7VyGgi9IluIxA9OiYp6yctr2aZ2So9vfJVDuW6ayILFNEhS5ku6KkCJTf"
[21] "0loWtIv0cWE8ZOVBawggXFsCgYBWw612Ggl74rit1ox2lXGacgGqhRzJj/BGcv1C"
[22] "6xk8ItnOOKMD5h8mxYgTFQ06gvExUwcwrS4+VkThykbf3SozZWoZBXFoiP6ygocN"
[23] "uKWGW7dIoFvkBPoT0cqwlV3DLQVBgYz0IDLARSwEjwvKsdOUPTzJeunwE5T9YwI2"
[24] "ovRaGQKBgF0zysxImSvnC8jQFB5+jw5dCnP8gXDljZPDJhxwlkbNc85ikA27vSkQ"
[25] "+ql0YOsgka3DH4ISOpMGJXaCTkI86OXtLlG0HBjLgiiyYQnFieQ1xPB3PfCPKWHl"
[26] "G84TmLUw9uxC08jV0r7UfIDBxv7kNGDLJqyTmsCYON9EXbbt03ac"            
[27] "-----END RSA PRIVATE KEY-----"      

# 比较纯文本格式和PEM格式,不相同
> identical(paste0(ca.txt,"\n",collapse = ""),ca.pem)
[1] FALSE

# 比较纯文本格式和pkcs1格式,相同
> identical(paste0(ca.txt,"\n",collapse = ""),ca.pkcs1)
[1] TRUE

3.2 取读ca.key的公钥并输出
在ca.key文件中,不仅包括了私钥信息还包括了公钥信息。有2个种方法,可以获取公钥信息。一是使用上面的私钥对象,取出公钥,二是使用read_pubkey()函数进行读取。

首先使用刚刚生成的cakey对象,来获取公钥。


> cakey$pubkey
[2048-bit rsa public key]
md5: 87be025db1f33785aafa00aa83388a8b
sha256: c03bc0d35b4593ff81cde4545b1aa62f80e754545297f30669bdcce29a910a45

再使用read_pubkey()函数,来获取公钥。


> cakey_pub<-read_pubkey("./ca.key");cakey_pub # public
[2048-bit rsa public key]
md5: 87be025db1f33785aafa00aa83388a8b
sha256: c03bc0d35b4593ff81cde4545b1aa62f80e754545297f30669bdcce29a910a45

# 比较2个结果,相同
> identical(cakey_pub,cakey$pubkey)
[1] TRUE

还没有公钥文件,我们可以输出这个文件,用pkcs1格式


# 输出公钥文件
> write_pkcs1(cakey_pub,"./ca_pub.key")

# 读取输出的公钥文件
> read_pubkey("./ca_pub.key")
[2048-bit rsa public key]
md5: 87be025db1f33785aafa00aa83388a8b
sha256: c03bc0d35b4593ff81cde4545b1aa62f80e754545297f30669bdcce29a910a45

3.3 取读ca.crt证书文件
除了能读取秘钥,还可以进行证书的读取。


# 读取证书文件
> file<-"ca.crt"
> cacrt<-read_cert(file, der = is.raw(file))

# 查看证书对象
> cacrt
[x509 certificate] myca.com
md5: 916c490f78b0f068a9ea6f7b0ded5bd5
sha1: be2eed543b4188fdc08bee8dfb0adf403e7437bf

# 查看证书链式对象 
> read_cert_bundle(file)
[[1]]
[x509 certificate] myca.com
md5: 916c490f78b0f068a9ea6f7b0ded5bd5
sha1: be2eed543b4188fdc08bee8dfb0adf403e7437bf

接下来,查看证书的文件存储格式,证书的文件格式是以PEM格式进行存储的。


# 以PEM格式查看证书内容
> cacrt.pem<-write_pem(cacrt);cacrt.pem
[1] "-----BEGIN CERTIFICATE-----\nMIID7TCCAtWgAwIBAgIUcV2+3ipz02Qccfqe5rT1sSY43LYwDQYJKoZIhvcNAQEL\nBQAwgYUxCzAJBgNVBAYTAlpIMQswCQYDVQQIDAJCSjEQMA4GA1UEBwwHQkVJSklO\nRzEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMREwDwYDVQQDDAht\neWNhLmNvbTEhMB8GCSqGSIb3DQEJARYSYnNzcGlyaXRAZ21haWwuY29tMB4XDTIy\nMTEzMDA5NDA0M1oXDTIzMTEzMDA5NDA0M1owgYUxCzAJBgNVBAYTAlpIMQswCQYD\nVQQIDAJCSjEQMA4GA1UEBwwHQkVJSklORzEhMB8GA1UECgwYSW50ZXJuZXQgV2lk\nZ2l0cyBQdHkgTHRkMREwDwYDVQQDDAhteWNhLmNvbTEhMB8GCSqGSIb3DQEJARYS\nYnNzcGlyaXRAZ21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC\nAQEA1iLmJeJHYeVutw6Ui+V/tZs2SS4GFzTWRkoRmmt4Z+5jQMt/dv94WbjmKyvN\nNrXiNiGz1jZQsw2Bj+22rSKjGEh4Qipjpcc+AOfl99V3diH8YM/cwj6dNFKqqmpJ\nHtzDSbhOudPbwDsFugq3dyVsV1hMKrlEBetI7Qj/8kZSie1KL+QS00G+ISCHUes8\nf/eFHgd7sMXpOb65NJhAKZGSeT49V+IeF1M82VJEyV+x1p/C3ppAL9PTt3RFftTQ\nJjXW48tIfS3R85E0libyeQnlxM3slEf2UnO16wq/7j3KmWiPD9vmtPnhNjKbBr6P\nbtAR+CAsSpxaVLMpA1PDydqsCQIDAQABo1MwUTAdBgNVHQ4EFgQU55Mc/d8s7WlF\n0HaorBq64rcFJXIwHwYDVR0jBBgwFoAU55Mc/d8s7WlF0HaorBq64rcFJXIwDwYD\nVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAP6Vfs0SX8035Qo3nccOf\niemkfsMoH8Jme7TNT8sv19hxdVhtHw5pgPxsJfb5Upwp5RjQogdruPBXW86MVgSh\nxYptVH94L4QIPZFLvuPzTE1j03/44jm1mwvOGu7jf27Bb683Ltp6MoL9yoJylEYl\nFwYaowelmZnkAFArdy/QG/tgMuW3wh1ThACg1ZKDcnw+ncX5oAzJIa7ydAIUjyJO\nQpJvtrPfV23bGds3swICxZIPNLE7iAN5z9br1DZNJ+GoMrgCHlrvPilagY/LKzWu\nq9+IwP6mVY7egc+os7FQKQ3nFbGBBAE41m9HKP6Tw8kUhK8HcaViuFHbUOeftv8F\nhQ==\n-----END CERTIFICATE-----\n"

# 以pkcs1格式查看证书内容,报错。
> cacrt.pkcs1<-write_pkcs1(cacrt);cacrt.pkcs1
Error in write_pkcs1(cacrt) : PKCS1 pubkey format only supports RSA keys

# 以纯文件的方式读取证书文件
> cacrt.txt<-readLines(file);cacrt.txt
 [1] "-----BEGIN CERTIFICATE-----"                                     
 [2] "MIID7TCCAtWgAwIBAgIUcV2+3ipz02Qccfqe5rT1sSY43LYwDQYJKoZIhvcNAQEL"
 [3] "BQAwgYUxCzAJBgNVBAYTAlpIMQswCQYDVQQIDAJCSjEQMA4GA1UEBwwHQkVJSklO"
 [4] "RzEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMREwDwYDVQQDDAht"
 [5] "eWNhLmNvbTEhMB8GCSqGSIb3DQEJARYSYnNzcGlyaXRAZ21haWwuY29tMB4XDTIy"
 [6] "MTEzMDA5NDA0M1oXDTIzMTEzMDA5NDA0M1owgYUxCzAJBgNVBAYTAlpIMQswCQYD"
 [7] "VQQIDAJCSjEQMA4GA1UEBwwHQkVJSklORzEhMB8GA1UECgwYSW50ZXJuZXQgV2lk"
 [8] "Z2l0cyBQdHkgTHRkMREwDwYDVQQDDAhteWNhLmNvbTEhMB8GCSqGSIb3DQEJARYS"
 [9] "YnNzcGlyaXRAZ21haWwuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC"
[10] "AQEA1iLmJeJHYeVutw6Ui+V/tZs2SS4GFzTWRkoRmmt4Z+5jQMt/dv94WbjmKyvN"
[11] "NrXiNiGz1jZQsw2Bj+22rSKjGEh4Qipjpcc+AOfl99V3diH8YM/cwj6dNFKqqmpJ"
[12] "HtzDSbhOudPbwDsFugq3dyVsV1hMKrlEBetI7Qj/8kZSie1KL+QS00G+ISCHUes8"
[13] "f/eFHgd7sMXpOb65NJhAKZGSeT49V+IeF1M82VJEyV+x1p/C3ppAL9PTt3RFftTQ"
[14] "JjXW48tIfS3R85E0libyeQnlxM3slEf2UnO16wq/7j3KmWiPD9vmtPnhNjKbBr6P"
[15] "btAR+CAsSpxaVLMpA1PDydqsCQIDAQABo1MwUTAdBgNVHQ4EFgQU55Mc/d8s7WlF"
[16] "0HaorBq64rcFJXIwHwYDVR0jBBgwFoAU55Mc/d8s7WlF0HaorBq64rcFJXIwDwYD"
[17] "VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAP6Vfs0SX8035Qo3nccOf"
[18] "iemkfsMoH8Jme7TNT8sv19hxdVhtHw5pgPxsJfb5Upwp5RjQogdruPBXW86MVgSh"
[19] "xYptVH94L4QIPZFLvuPzTE1j03/44jm1mwvOGu7jf27Bb683Ltp6MoL9yoJylEYl"
[20] "FwYaowelmZnkAFArdy/QG/tgMuW3wh1ThACg1ZKDcnw+ncX5oAzJIa7ydAIUjyJO"
[21] "QpJvtrPfV23bGds3swICxZIPNLE7iAN5z9br1DZNJ+GoMrgCHlrvPilagY/LKzWu"
[22] "q9+IwP6mVY7egc+os7FQKQ3nFbGBBAE41m9HKP6Tw8kUhK8HcaViuFHbUOeftv8F"
[23] "hQ=="                                                            
[24] "-----END CERTIFICATE-----"                                       

# 验证纯文本的证书与PEM格式,相同。
> identical(paste0(cacrt.txt,"\n",collapse = ""),cacrt.pem)
[1] TRUE

最后,可以把证书重写到一个新文件中,再读取,可得到完成一样的证书数据。


> write_pem(cacrt,"cacrt.crt.bak")
> read_cert("cacrt.crt.bak")
[x509 certificate] myca.com
md5: 916c490f78b0f068a9ea6f7b0ded5bd5
sha1: be2eed543b4188fdc08bee8dfb0adf403e7437bf

4. 获取网站证书并验证

如果我们想让自己的网站支持HTTPS,实现SSL/TLS协议时就需要用到证书;或者当我们想配置github的git的自动权限访问时,也需要使用用到证书;当我们在使用Linux,想进行无密码登陆时,这时也可以用证书。

利用openssl工具,我们可以获得各种网站的证书,查看网站的证书的相关信息,数字签名的信息,通过HTTPS传输的加密算法等信息,最后可以验证证书是否是合法的。

4.1 在浏览器网站证书
我们访问R的官方网站,https://www.r-project.org/,网站是HTTPS的,我们可以手动查看网站的证书。在证书中的,证书颁发者,SHA1,SHA256,有效期,公钥等的信息。

我们可以手动下载证书文件,在本地进行打开。

4.2 用R语言来下载证书
接下来,我们可以用R语言的程序,来获取证书信息,


# 证书下载
> cert <- download_ssl_cert("www.r-project.org")

查看当前证书,上级证书,一直到root证书。


> cert
[[1]]
[x509 certificate] *.r-project.org
md5: 11a9fee5a83206c063a203c97f71481b
sha1: 03c310e4971981154ada3a5df46206dadfb82172

[[2]]
[x509 certificate] Sectigo RSA Domain Validation Secure Server CA
md5: adab5c4df031fb9299f71ada7e18f613
sha1: 33e4e80807204c2b6182a3a14b591acd25b5f0db

[[3]]
[x509 certificate] USERTrust RSA Certification Authority
md5: 285ec909c4ab0d2d57f5086b225799aa
sha1: d89e3bd43d5d909b47a18977aa9d5ce36cee184c

4.3 查看当前证书的详细

取当前证书,看证书的信息。当前证书允许的域名。


# 取当前证书
> cert_data<-cert[[1]]

# 允许域名
> cert_data$alt_names
[1] "*.r-project.org" "r-project.org"  

# 查看cert_data的数据结构
> str(cert_data)
List of 8
 $ subject    : chr "CN=*.r-project.org"
 $ issuer     : chr "CN=Sectigo RSA Domain Validation Secure Server CA,O=Sectigo Limited,L=Salford,ST=Greater Manchester,C=GB"
 $ algorithm  : chr "sha256WithRSAEncryption"
 $ signature  : raw [1:256] b1 2f f9 a5 ...
 $ validity   : chr [1:2] "Oct 23 00:00:00 2022 GMT" "Nov 23 23:59:59 2023 GMT"
 $ self_signed: logi FALSE
 $ alt_names  : chr [1:2] "*.r-project.org" "r-project.org"
 $ pubkey     :List of 5
  ..$ type       : chr "rsa"
  ..$ size       : int 2048
  ..$ ssh        : chr "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQ/cx8HyMW9SCLJsC/UKaTh/RskQ33Leicy0prlBc2Dm3Tk/m1Dn7cpwGZ ..."
  ..$ fingerprint: 'hash' raw [1:32] a7 68 11 fb ...
  ..$ data       :List of 2
  .. ..$ e: 'bignum' raw [1:3] 01 00 01
  .. ..$ n: 'bignum' raw [1:257] 00 d0 fd cc ...

4.4 查看公钥信息
查看公钥信息,使用了RSA的2048位加密,查看公钥的二进制格式,就与网上在看到的公钥内容是一致的。


# 查看公钥为2048位的RSA加密
> cert_data$pubkey
[2048-bit rsa public key]
md5: 6b372d9b5c5759fbb28baf03c609730a
sha256: a76811fbe1608aeeb74f077b63e07c8fea82fdf4789c01c7b5b975a8958eb12b

# 公钥的ssh码
> cert_data$pubkey$ssh
[1] "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDQ/cx8HyMW9SCLJsC/UKaTh/RskQ33Leicy0prlBc2Dm3Tk/m1Dn7cpwGZQrsS4ak1IaV5WroeJjWUzEiaJH5Ky4vJOGWJYXoXw5THDFxraaCk4CPd/cQuFkezY6iuEYORuNYoukV9xgXhfaGJN4K8Gan6Hi8syY6HqnOiSt887GUZckO7TQF3RishPlbLzx0G17inlhigDFtoFenG/x043EwkIFJ6pz1jA8h/Us29Rw1+853AwNZ/nOptaUFku6W3uXgf4TLYUn6NzPSKY6lJ34gpSoBVQIIU8hjz2Y3cwlIzgQnrw2qlzDmFmiZtjPTaMrvBzs5QHfsgOBHvc5j/"

# 查看公钥的二进制格式
> write_der(cert_data$pubkey)
  [1] 30 82 01 22 30 0d 06 09 2a 86 48 86 f7 0d 01 01 01 05 00 03 82 01 0f 00 30 82 01 0a
 [29] 02 82 01 01 00 d0 fd cc 7c 1f 23 16 f5 20 8b 26 c0 bf 50 a6 93 87 f4 6c 91 0d f7 2d
 [57] e8 9c cb 4a 6b 94 17 36 0e 6d d3 93 f9 b5 0e 7e dc a7 01 99 42 bb 12 e1 a9 35 21 a5
 [85] 79 5a ba 1e 26 35 94 cc 48 9a 24 7e 4a cb 8b c9 38 65 89 61 7a 17 c3 94 c7 0c 5c 6b
[113] 69 a0 a4 e0 23 dd fd c4 2e 16 47 b3 63 a8 ae 11 83 91 b8 d6 28 ba 45 7d c6 05 e1 7d
[141] a1 89 37 82 bc 19 a9 fa 1e 2f 2c c9 8e 87 aa 73 a2 4a df 3c ec 65 19 72 43 bb 4d 01
[169] 77 46 2b 21 3e 56 cb cf 1d 06 d7 b8 a7 96 18 a0 0c 5b 68 15 e9 c6 ff 1d 38 dc 4c 24
[197] 20 52 7a a7 3d 63 03 c8 7f 52 cd bd 47 0d 7e f3 9d c0 c0 d6 7f 9c ea 6d 69 41 64 bb
[225] a5 b7 b9 78 1f e1 32 d8 52 7e 8d cc f4 8a 63 a9 49 df 88 29 4a 80 55 40 82 14 f2 18
[253] f3 d9 8d dc c2 52 33 81 09 eb c3 6a a5 cc 39 85 9a 26 6d 8c f4 da 32 bb c1 ce ce 50
[281] 1d fb 20 38 11 ef 73 98 ff 02 03 01 00 01

# 查看公钥数据
> cert_data$pubkey$data
$e
[b] 65537
$n
[b] 26382720270417477837617835499791330099049934775392664891485281047561411831161618531639849698257940022133596595793360566082157334663831597661390020187366330377887609444158710396573956877965613421020593308923784748020878445065836239835939589641288489663966645774920702533024654777130568392213769053338143063817255841711707909827551784702236553682744092755623610745991474611454202317512454804265930433899882101055065400009265523412830694180236095124621448935253985091450512509725554745453130660854770715808981111924477167623114187044856057832860089329518157485613424693402698364749754164433810264444699764245619172153599

4.5 验证证书是否真实有效
验证证书是否真实有效,ca_bundle()函数可以获得所有root证书的机构,通过比对当前证书的root机构与登记的机构比对,从而判断当前证书的真实性。


# 验证证书是否真实有效
> cert_verify(cert, ca_bundle())
[1] TRUE

# 查看root证书的机构的前6条
> head(ca_bundle())
[[1]]
[x509 certificate] GlobalSign Root CA
md5: 3e455215095192e1b75d379fb187298a
sha1: b1bc968bd4f49d622aa89a81f2150152a41d829c

[[2]]
[x509 certificate] GlobalSign
md5: 9414777e3e5efd8f30bd41b0cfe7d030
sha1: 75e0abb6138512271c04f85fddde38e4b7242efe

[[3]]
[x509 certificate] VeriSign Class 3 Public Primary Certification Authority - G3
md5: cd68b6a7c7c4ce75e01d4f5744619209
sha1: 132d0d45534b6997cdb2d5c339e25576609b5cc6

[[4]]
[x509 certificate] Entrust.net Certification Authority (2048)
md5: ee2931bc327e9ae6e8b5f751b4347190
sha1: 503006091d97d4f5ae39f7cbe7927d7d652d3431

[[5]]
[x509 certificate] Baltimore CyberTrust Root
md5: acb694a59c17e0d791529bb19706a6e4
sha1: d4de20d05e66fc53fe1a50882c78db2852cae474

[[6]]
[x509 certificate] AddTrust External CA Root
md5: 1d3554048578b03f42424dbf20730a3f
sha1: 02faf3e291435468607857694df5e45b68851868

4.6 导出密钥或证书
使用write_pem() 函数将钥匙或证书导出为标准的base64 PEM格式。对于私钥,可以设置一个密码。


# 查看证书的密文
> write_pem(cert_data)
[1] "-----BEGIN CERTIFICATE-----\nMIIGNzCCBR+gAwIBAgIQVDDlPXe+N3mjxP1zcGBexzANBgkqhkiG9w0BAQsFADCB\njzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4G\nA1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTcwNQYDVQQD\nEy5TZWN0aWdvIFJTQSBEb21haW4gVmFsaWRhdGlvbiBTZWN1cmUgU2VydmVyIENB\nMB4XDTIyMTAyMzAwMDAwMFoXDTIzMTEyMzIzNTk1OVowGjEYMBYGA1UEAwwPKi5y\nLXByb2plY3Qub3JnMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0P3M\nfB8jFvUgiybAv1Cmk4f0bJEN9y3onMtKa5QXNg5t05P5tQ5+3KcBmUK7EuGpNSGl\neVq6HiY1lMxImiR+SsuLyThliWF6F8OUxwxca2mgpOAj3f3ELhZHs2OorhGDkbjW\nKLpFfcYF4X2hiTeCvBmp+h4vLMmOh6pzokrfPOxlGXJDu00Bd0YrIT5Wy88dBte4\np5YYoAxbaBXpxv8dONxMJCBSeqc9YwPIf1LNvUcNfvOdwMDWf5zqbWlBZLult7l4\nH+Ey2FJ+jcz0imOpSd+IKUqAVUCCFPIY89mN3MJSM4EJ68Nqpcw5hZombYz02jK7\nwc7OUB37IDgR73OY/wIDAQABo4IDATCCAv0wHwYDVR0jBBgwFoAUjYxexFStiuF3\n6Zv5mwXhuAGNYeEwHQYDVR0OBBYEFAnIMghgCgq5FuZgZW2gz333Rr0yMA4GA1Ud\nDwEB/wQEAwIFoDAMBgNVHRMBAf8EAjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggr\nBgEFBQcDAjBJBgNVHSAEQjBAMDQGCysGAQQBsjEBAgIHMCUwIwYIKwYBBQUHAgEW\nF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAgGBmeBDAECATCBhAYIKwYBBQUHAQEE\neDB2ME8GCCsGAQUFBzAChkNodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29S\nU0FEb21haW5WYWxpZGF0aW9uU2VjdXJlU2VydmVyQ0EuY3J0MCMGCCsGAQUFBzAB\nhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTApBgNVHREEIjAggg8qLnItcHJvamVj\ndC5vcmeCDXItcHJvamVjdC5vcmcwggF/BgorBgEEAdZ5AgQCBIIBbwSCAWsBaQB3\nAK33vvp8/xDIi509nB4+GGq0Zyldz7EMJMqFhjTr3IKKAAABhAKZWJgAAAQDAEgw\nRgIhAJdfvjFXbRU053wGkFTCa6M/FZ9AQXpIWKw3XGmtclmPAiEA6FRxqIJ2qam2\naLj5lvj/YuiD+ohMvaeRL78TlAt1dSoAdgB6MoxU2LcttiDqOOBSHumEFnAyE4VN\nO9IrwTpXo1LrUgAAAYQCmViyAAAEAwBHMEUCIQCWAMENLlPBh73qMoqix/AIwr/g\niLrKwc4yKkcXNY49bQIgQWjhgFm/o/QL3NuoyaY5Gs0J7BWjJr4AHQn14cFmKAAA\ndgDoPtDaPvUGNTLnVyi8iWvJA9PL0RFr7Otp4Xd9bQa9bgAAAYQCmVh7AAAEAwBH\nMEUCIQCV0vEGrO3f/pH9ew1fNwFE40nrB17r/8XAwyiWI5cg7gIgZ3RQ3PKI1zFq\npiW86XgKgU9EnW1GjNzKJfxb4SMPuJkwDQYJKoZIhvcNAQELBQADggEBALEv+aVn\ndC0VLCw+CoBYt5cpWkwPfKpWewAC9fw2Q9womhmrN9+C51kX0JZpEE2V1oG5lahp\n5fUi5XwZRT+/1wNIz5GDLMbumY+m7dQp6NE+XApYSd/J+HnLoKAuVI+YosOtHhF/\n07cMNogiVhEldeOweo8Z8YxCmb/EzSY30wdHNNASf5s2TQ0tlZ1NzKTzt/gpOXDp\njgQJE4zXamym3qNGDumhbEWKozQqLVo2OOYgak8OkeDzar48MQdc3vvtO0B1heRh\nvZ2FezAFWDfHcldXJK2W/DOpprE+oIRjlYKztXG3r/aYpu59vMsAIhGWuC6Vg2Yx\nk8Umv/fhAjEe/xc=\n-----END CERTIFICATE-----\n"

本文尝试了使用openssl 的命令行工具,和R语言中的openssl包的秘钥和x509证书管理的函数,进行了秘钥生成,证书生成,证书管理,证书下载,证书验证等的功能尝试。里面有不少的密码学的内容,是需要我们先理解后再进行操作的。

唯一遗憾的就是不能直接用R语言进行证书的生成。openssl博大精深,一个包支持非常多的密码学的内容。

本文代码已上传到github: https://github.com/bsspirit/encrypt/blob/master/cert.r

转载请注明出处:
http://blog.fens.me/r-crypto-openssl-cert/

打赏作者