要想知道怎么加载密钥和证书,首先要知道现有PKI体系中密钥和证书是怎么生成和保存的,符合什么标准。现有数字证书都是基于 X509标准 ,这中间已经形成了一系列的标准体系,其中比较重要的是 PKCS系列 。
一、证书相关标准及格式
PKCS(Public-Key Cryptography Standards),即公钥密码标准,是由美国RSA数据安全公司及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议,目前形成了多个标准 [1] 。
- PKCS#1:RSA加密标准。PKCS#1定义了RSA公钥函数的基本格式标准,特别是数字签名。它定义了数字签名如何计算,包括待签名数据和签名本身的格式;它也定义了PSA公/私钥的语法。
- PKCS#8:描述私有密钥信息格式,该信息包括公开密钥算法的私有密钥以及可选的属性集等。
- PKCS#12:定义了包含私钥与公钥证书(public key certificate)的文件格式。私钥采用密码(password)保护。常见的P12就履行了PKCS#12。
在X509证书中,证书组成结构标准用ASN.1(一种标准的语言)来进行描述,X.509 v3数字证书结构如下 [2] :
-
证书
- ...
- 公钥算法
- 主题公钥
- 此日期前无效
- 此日期后无效
- 版本号
- 序列号
- 签名算法
- 颁发者
- 证书有效期
- 主题
- 主题公钥信息
- 颁发者唯一身份信息(可选项)
- 主题唯一身份信息(可选项)
- 扩展信息(可选项) - 证书签名算法
- 数字签名
而证书文件的格式一般包括以下几种 [3] :
- *.DER或*.CER文件(X.509 DER 编码的后缀):二进制格式文件,只含有证书信息,不包含私钥。
- *.CRT文件(X.509 DER 编码的后缀):可以是二进制格式文件,也可以是文本格式文件,一般均为文本格式,功能与*.DER及*.CER证书文件相同。
- *.PEM文件(X.509 PAM 编码的后缀):一般是文本格式文件,可以存放证书或私钥,或者两者都包含。*.PEM文件如果只包含私钥,一般用*.KEY文件代替。
- *.PFX或*.P12文件(PKCS#12常用后缀):二进制格式文件,同时包含证书和私钥,且一般有密码保护。
以上几种格式都是可以互相转换的,此外还包括PKCS#7标准下的*.P7B,*.P7C,*.SPC等格式。
二、证书生成及加载
为了要加载证书,我们首先需要生成密钥及证书,生成工具使用openssl [4] 。而对于题主的问题,一般来说, 私钥文件是加密的,而公钥和证书是不太需要加密的 ,并且目前 rsa的证书是使用PKCS#1标准的 ,而 ecdsa等椭圆曲线的公钥算法是使用PKCS#8标准 的,这里我们都测试下。
1.rsa证书的生成和加载
- rsa证书生成
(1)先生成rsa的私钥,密钥长度设置为
2048bit
,使用
ase256
加密,加密密码为
1234
,生成的密钥保存在
private.pem
文件中。
$openssl genrsa -aes256 -passout pass:1234 -out ~/Downloads/cert/private.pem 2048
可以直接以文本形式打开,内容如下:
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,6EE6DA1B69406CFC40AB510AE88FBB10
NXJDpdlMaKo2VnrHswo5FyMgfskWUK2naGsrYygElJOUrjWRuyjY+Rv4kuR5kgs8
TbdjGokUNKA/JDvLRnCov2oydkXEkcinUt/0DmPuq8ow+NRMygBek0xSV8oDW0N7
ntMGBz6YqzorTuJLVmSH1EkLmXiGrNGtH1osT4QfTXh+3lS3RZpf4GY/6yo00NZV
wyVciE9V4weS32xZprx48Z/ShI6PCYTH44R1NzkPfwpf60UoQyTM+2EOH0qjr2tu
fnGb9zmaj3hB9blGOIChd2VFUNVfTLXKgMkoumLyOHMQq2oN96QNpN0Cay2nNmXj
v8JYnSq819D/zjIDJcY4ah2DGr3kIJTUVnNHrqxOrXw5H6h8DmbJ6Oj5Fw3ZV1mO
IAPelGg2mh8c0X6mzcjx2hjQzvmp7IGfx6hDWHsVw1o0pg0ByLMGMcAP1RD9HPFt
PhrgI43hptt/9O/1F5u7TEQh62xyCjJR9+lY3A+gNRflfT/ykJUFowHGqeuMeAMk
hqoe1iwVZJxH/5KiVvB4Ay6XiOC4rKuVBcd0s/FrQT+U+b0ji9UzXdRSPgoVnQp3
W6vYFLwgSY124oPJlUvoAT4B+/0kpwQrSwrXM0RPJxGQ5FRNULbOByyra1ihCaVa
6pkN0DXUW91OIjhxus7HyKmETvKwC8LVVdUXoPK8pjOjM6XJ+JcKQsL/n6JWFhcJ
M8xBS+JttKeWmWOanT3FteI8Aq1mzI3qmIMXBx/pwelERI7G/gAgXtyMYusfzrG0
1020L+8OJZLPxbIrndIj7kamhQoH94isUGmy3F6I1ga92tXRxDwuw9Z8+IxDqigV
L5hQ31hDLjPcvOJ8CEy8ZLwtfbSh4kHb/44AE+wsv81G0YIWFf0wYP2sdOUPqJ2+
g9vR6XuLLd2MuKHVhtgvTE3XdDLUq9CUas0x5ii1o01ta2RQ+x57j6tq2Du560wH
KRgCk2wBaFXJVDVBvyJccqpqHCCWT3GMWa9jIh5D5LdqBL+JX9zjNUY7in4ki9tz
kudvGRZt+5EmdMv9fW6zY1xbTIPnUsgtjWadwqPcZW/ch8HiOALEwfem6YGJ8Edw
cuCALwEJof+xBAzPEMhhlAYBJveM+LsfZWo9Ie5vGAHdsetzT8svlITJbbk4OaTP
Kz+anXM9rmrFytAMbnS18IjSqZXe4kQrMHd5dk5bJX3nT1DdXHL/29W69Nc+k1uc
VhRg+tvYydfwfgyPmkikEV8FkRxvaQPSzzJgJfBdpyTYsAnM8s3kXi1aRpy19z2g
5T+yihaqwt2Ae/1GFyUdAABOop3EBy9Z384NJjevfJUeWFDIwiboQM4Aabg/hRky
ZQShcFp9kMs7eTBPHDP7NBDkWEYDXg491UFifP1faPI7QUfj8PLNBwyEdjQOr9Dq
/xknnhon2rY25uE5OxTxvw0JH5jk3iWntctdM5bLy2kOCbNpfnLJw3SQc1fazWLR
P9mjVAGYAx59Tj9gawxZHXciS6PMcnGsmlTFMZcscPfeGh5VopV2gc8F7hjd/yff
phYC8+bsqAJUp+DcQkQ0fM5ejJ73uAbmRDoqGjpXrXQJoiTH9MqBCRefvag/D6Jt
-----END RSA PRIVATE KEY-----
(2)根据私钥生成rsa的公钥,保存在
public.pem
文件中。
$openssl rsa -in ~/Downloads/cert/private.pem -pubout -out ~/Downloads/cert/public.pem
可以以文本形式打开,内容如下:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3BS4210kTXzE0Za3bTW/
zkECcxYBPywzQD1x3yxgQB8gU8q8ufcWpP0gS+So/0/Cqhg3LkE4xGEGPxB7rpfM
iRlVz5/a0hXMqtpsAXeqNml7divUBiBuJEHEI71AX45z1QdDcXTsh7xBuWBxi8XX
QPdQ7c6RUGipipTT06WBHmmB1xj3ZXYBdNDQt0RU1QVT3YX5qmYL+vq6mAHI/qjM
Z0bccgobjfQJNh6Zt2uAyR1Dbw3UyKwO21EqWl/ZGoCLtwKg+cqrRq6MzFADfjyi
xRbx3TftSniKRqdqIDFpdg4M5IdAb1drTEys+tUZTpP2RPWq6jOx2RY6EC8n+qQH
EQIDAQAB
-----END PUBLIC KEY-----
(3)根据私钥生成自签名证书,保存在
cert.crt
文件中。
$openssl req -new -x509 -days 365 -key ~/Downloads/cert/private.pem -out ~/Downloads/cert/cert.crt
可以以文本形式打开,内容如下:
-----BEGIN CERTIFICATE-----
MIIDyzCCArOgAwIBAgIUS5zyqL4+WMa2Yhm2CD4JBgbiN5AwDQYJKoZIhvcNAQEL
BQAwdTELMAkGA1UEBhMCQ04xEDAOBgNVBAgMB2JlaWppbmcxEDAOBgNVBAcMB2Jl
aWppbmcxCzAJBgNVBAoMAkJKMQ0wCwYDVQQLDAR0ZXN0MQ0wCwYDVQQDDAR0ZXN0
MRcwFQYJKoZIhvcNAQkBFgh0ZXN0LmNvbTAeFw0yMTA3MDgwMTE5MjVaFw0yMjA3
MDgwMTE5MjVaMHUxCzAJBgNVBAYTAkNOMRAwDgYDVQQIDAdiZWlqaW5nMRAwDgYD
VQQHDAdiZWlqaW5nMQswCQYDVQQKDAJCSjENMAsGA1UECwwEdGVzdDENMAsGA1UE
AwwEdGVzdDEXMBUGCSqGSIb3DQEJARYIdGVzdC5jb20wggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDcFLjbXSRNfMTRlrdtNb/OQQJzFgE/LDNAPXHfLGBA
HyBTyry59xak/SBL5Kj/T8KqGDcuQTjEYQY/EHuul8yJGVXPn9rSFcyq2mwBd6o2
aXt2K9QGIG4kQcQjvUBfjnPVB0NxdOyHvEG5YHGLxddA91DtzpFQaKmKlNPTpYEe
aYHXGPdldgF00NC3RFTVBVPdhfmqZgv6+rqYAcj+qMxnRtxyChuN9Ak2Hpm3a4DJ
HUNvDdTIrA7bUSpaX9kagIu3AqD5yqtGrozMUAN+PKLFFvHdN+1KeIpGp2ogMWl2
Dgzkh0BvV2tMTKz61RlOk/ZE9arqM7HZFjoQLyf6pAcRAgMBAAGjUzBRMB0GA1Ud
DgQWBBS14p4tmyZWdAFma7qf6H9+9RTyxDAfBgNVHSMEGDAWgBS14p4tmyZWdAFm
a7qf6H9+9RTyxDAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQA/
XABWdZOa2Sifz31v+etVirpVeUItTq1Np3E8G4wZ6ljn8KACSSifBSYY6HoXyriM
vo9Q780gffOQbi2IYY23yjEGAWHtcqyUKZPHJJdwQMxLOOxXeJ+62o4YqOPkYe69
vObS//rvCARvh25n7EcrWMuyUNWP3QlrbReO+n+bzx7LkPVryVu6CSEG0QqZaem4
GRBWdrK7kq17kl3vGHoDUSBF/7ZyVuMT0vw1I01obq9aX3FtOQFRqV38zqbs0oJS
zI6A+oImjdMhq56bMrgGUzyrgENAXVa6AmBk2Q7TNBJ6t9thuUbeWaBNXJyEkLLq
rBE2zoQwSulTd+be1baa
-----END CERTIFICATE-----
也可以使用
openssl
查看证书的命令显示证书详细内容。
$openssl x509 -in cert.crt -noout -text
结果如下:
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
4b:9c:f2:a8:be:3e:58:c6:b6:62:19:b6:08:3e:09:06:06:e2:37:90
Signature Algorithm: sha256WithRSAEncryption
Issuer: C = CN, ST = beijing, L = beijing, O = BJ, OU = test, CN = test, emailAddress = test.com
Validity
Not Before: Jul 8 01:19:25 2021 GMT
Not After : Jul 8 01:19:25 2022 GMT
Subject: C = CN, ST = beijing, L = beijing, O = BJ, OU = test, CN = test, emailAddress = test.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:dc:14:b8:db:5d:24:4d:7c:c4:d1:96:b7:6d:35:
bf:ce:41:02:73:16:01:3f:2c:33:40:3d:71:df:2c:
60:40:1f:20:53:ca:bc:b9:f7:16:a4:fd:20:4b:e4:
a8:ff:4f:c2:aa:18:37:2e:41:38:c4:61:06:3f:10:
7b:ae:97:cc:89:19:55:cf:9f:da:d2:15:cc:aa:da:
6c:01:77:aa:36:69:7b:76:2b:d4:06:20:6e:24:41:
c4:23:bd:40:5f:8e:73:d5:07:43:71:74:ec:87:bc:
41:b9:60:71:8b:c5:d7:40:f7:50:ed:ce:91:50:68:
a9:8a:94:d3:d3:a5:81:1e:69:81:d7:18:f7:65:76:
01:74:d0:d0:b7:44:54:d5:05:53:dd:85:f9:aa:66:
0b:fa:fa:ba:98:01:c8:fe:a8:cc:67:46:dc:72:0a:
1b:8d:f4:09:36:1e:99:b7:6b:80:c9:1d:43:6f:0d:
d4:c8:ac:0e:db:51:2a:5a:5f:d9:1a:80:8b:b7:02:
a0:f9:ca:ab:46:ae:8c:cc:50:03:7e:3c:a2:c5:16:
f1:dd:37:ed:4a:78:8a:46:a7:6a:20:31:69:76:0e:
0c:e4:87:40:6f:57:6b:4c:4c:ac:fa:d5:19:4e:93:
f6:44:f5:aa:ea:33:b1:d9:16:3a:10:2f:27:fa:a4:
07:11
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Key Identifier:
B5:E2:9E:2D:9B:26:56:74:01:66:6B:BA:9F:E8:7F:7E:F5:14:F2:C4
X509v3 Authority Key Identifier:
keyid:B5:E2:9E:2D:9B:26:56:74:01:66:6B:BA:9F:E8:7F:7E:F5:14:F2:C4
X509v3 Basic Constraints: critical
CA:TRUE
Signature Algorithm: sha256WithRSAEncryption
3f:5c:00:56:75:93:9a:d9:28:9f:cf:7d:6f:f9:eb:55:8a:ba:
55:79:42:2d:4e:ad:4d:a7:71:3c:1b:8c:19:ea:58:e7:f0:a0:
02:49:28:9f:05:26:18:e8:7a:17:ca:b8:8c:be:8f:50:ef:cd:
20:7d:f3:90:6e:2d:88:61:8d:b7:ca:31:06:01:61:ed:72:ac:
94:29:93:c7:24:97:70:40:cc:4b:38:ec:57:78:9f:ba:da:8e:
18:a8:e3:e4:61:ee:bd:bc:e6:d2:ff:fa:ef:08:04:6f:87:6e:
67:ec:47:2b:58:cb:b2:50:d5:8f:dd:09:6b:6d:17:8e:fa:7f:
9b:cf:1e:cb:90:f5:6b:c9:5b:ba:09:21:06:d1:0a:99:69:e9:
b8:19:10:56:76:b2:bb:92:ad:7b:92:5d:ef:18:7a:03:51:20:
45:ff:b6:72:56:e3:13:d2:fc:35:23:4d:68:6e:af:5a:5f:71:
6d:39:01:51:a9:5d:fc:ce:a6:ec:d2:82:52:cc:8e:80:fa:82:
26:8d:d3:21:ab:9e:9b:32:b8:06:53:3c:ab:80:43:40:5d:56:
ba:02:60:64:d9:0e:d3:34:12:7a:b7:db:61:b9:46:de:59:a0:
4d:5c:9c:84:90:b2:ea:ac:11:36:ce:84:30:4a:e9:53:77:e6:
de:d5:b6:9a
- go加载解析rsa证书
(1)私钥解析
首先需要解析pem文件,
skBytes
为pem文件读取的内容。
skBlock,_ := pem.Decode(skBytes)
然后再进行解密,
skStr,err := x509.DecryptPEMBlock(skBlock,[]byte("1234"))
最后使用PKCS#1的解析方法解析私钥,
sk,err := x509.ParsePKCS1PrivateKey(skStr)
(2)公钥解析
先解析pem文件,
pkBlock,_ := pem.Decode(pkBytes)
再使用PKCS#1的解析方法解析公钥,
pk,err := x509.ParsePKIXPublicKey(pkBlock.Bytes)
(3)证书解析
先解析pem文件,
certBlock,_ := pem.Decode(certBytes)
再解析证书,
cert,err := x509.ParseCertificate(certBlock.Bytes)
(4)完整代码
package main
import (
"crypto/ecdsa"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"time"
func handleError(err error) {
if err != nil {
panic(err)
func main() {
//私钥解析
fmt.Println("================解析私钥================")
//打开私钥文件
skFile,err := os.Open("./private.pem")
handleError(err)
fileinfo,err := skFile.Stat()
handleError(err)
skBytes := make([]byte,fileinfo.Size())
n,err := skFile.Read(skBytes)
handleError(err)
fmt.Printf("私钥文件内容为:\n%s\n",skBytes[:n])
//解析pem文件
skBlock,_ := pem.Decode(skBytes)
//解密,解密密钥为"1234"
skStr,err := x509.DecryptPEMBlock(skBlock,[]byte("1234"))
handleError(err)
//解析rsa私钥
sk,err := x509.ParsePKCS1PrivateKey(skStr)
handleError(err)
fmt.Printf("rsa私钥D:%x\n长度为:%d bit\n",sk.D,sk.D.BitLen())
fmt.Printf("rsa私钥E:%d\n",sk.E)
skFile.Close()
fmt.Println("================解析私钥成功!================")
time.Sleep(1*time.Second)
fmt.Println()
//公钥解析
fmt.Println("================解析公钥================")
pkFile,err := os.Open("./public.pem")
handleError(err)
fileinfo,err = pkFile.Stat()
handleError(err)
pkBytes := make([]byte,fileinfo.Size())
n,err = pkFile.Read(pkBytes)
handleError(err)
fmt.Printf("公钥文件内容为:\n%s\n",pkBytes[:n])
//解析pem文件
pkBlock,
_ := pem.Decode(pkBytes)
//解析公钥
pk,err := x509.ParsePKIXPublicKey(pkBlock.Bytes)
handleError(err)
switch pub := pk.(type) {
case *rsa.PublicKey:
fmt.Printf("rsa公钥E:%d\n",pub.E)
fmt.Printf("rsa公钥N:%x\n",pub.N)
fmt.Printf("公钥长度:%d bit\n",pub.N.BitLen())
default:
panic("公钥解析错误!")
pkFile.Close()
fmt.Println("================解析公钥成功!================")
time.Sleep(1*time.Second)
fmt.Println()
//证书解析
fmt.Println("================解析证书================")
certFile,err := os.Open("./cert.crt")
handleError(err)
fileinfo,err = certFile.Stat()
handleError(err)
certBytes := make([]byte,fileinfo.Size())
n,err = certFile.Read(certBytes)
handleError(err)
fmt.Printf("证书内容为:\n%s\n",certBytes[:n])
//解析pem文件
certBlock,_ := pem.Decode(certBytes)
//解析证书
cert,err := x509.ParseCertificate(certBlock.Bytes)
handleError(err)
fmt.Println(cert.Issuer)
switch pub := cert.PublicKey.(type) {
case *rsa.PublicKey:
fmt.Printf("rsa公钥E:%d\n",pub.E)
fmt.Printf("rsa公钥N:%x\n",pub.N)
fmt.Printf("公钥长度:%d bit\n",pub.N.BitLen())
default:
panic("公钥解析错误!")
certFile.Close()
fmt.Println("================解析证书成功!================")
2.ecdsa证书的生成和加载
- ecdsa证书生成
(1)先生成ecdsa的私钥,使用
256bit
安全参数的椭圆曲线
prime256v1
,生成的密钥保存在
ecprivate.pem
文件中。
$openssl ecparam -name prime256v1 -genkey -out ecprivate.pem
可以直接以文本形式打开,内容如下:
-----BEGIN EC PARAMETERS-----
BggqhkjOPQMBBw==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIJP2vEK7lfAwcNyZLZ353uer+VW1if27Q1pphTgrk9N0oAoGCCqGSM49
AwEHoUQDQgAE1ji5tR1YPeBLZuzZPdyGka0BuY//XlOrNOeoT01pONJPSFLdCQkf
vZtsPF/2h5jCSHcf4gm8+BZx6RFKN6IL7g==
-----END EC PRIVATE KEY-----
(2)由于直接生成无法加密,所以需要再进行加密,加密密码为1234 ,加密后私钥保存在
ecprivate_pkcs8.pem
文件中。
$openssl pkcs8 -in ecprivate.pem -topk8 -out ecprivate_pkcs8.pem -passout pass:1234
可以直接以文本形式打开,内容如下:
-----BEGIN ENCRYPTED PRIVATE KEY-----
MIHsMFcGCSqGSIb3DQEFDTBKMCkGCSqGSIb3DQEFDDAcBAhlHcHQWESSEQICCAAw
DAYIKoZIhvcNAgkFADAdBglghkgBZQMEASoEEAlt0W/qlZJpAc2v0AIAgAMEgZC7
pi6Z3VXOR734XOltNo6r9+IXW+cDhKbBEIZtOnpKnJ9WqYi5A+KG1/zOpCfEKE0v
v0+vxu0YleJRmDw2vUH6fAMiknsw6/BiV1+hybDQMLm/C9sK0fMDDhY9yZlGZxE3
aU/2KMJwkh/JHz6qAi+Ol3kSArxmJ5tLF05YZe5O1XDgBnoCC69nxG0fcpRWDuo=
-----END ENCRYPTED PRIVATE KEY-----
(3)根据私钥生成公钥,保存在
ecpublic.pem
中。
$openssl pkey -in ecprivate_pkcs8.pem -pubout -out ecpublic.pem
(4)生成公钥证书,保存在
eccert.crt
中。
$openssl req -new -x509 -days 365 -key ~/Downloads/cert/ecprivate_pkcs8.pem -out ~/Downloads/cert/eccert.crt
- go解析ecdsa证书
(1)私钥解析
在解析私钥(加密形式)的时候,
始终不能正确解析出来
,初步猜测可能是因为
openssl
中
pkcs8
加密和解析模块
和go实现的
不太一样
,所以没有测试成功,也希望有了解的能说明下原因。
(2)公钥解析
先解析pem文件,
pkBlock,_ := pem.Decode(pkBytes)
再解析公钥,椭圆曲线公钥算法一般使用PKCS#8的解析方法,
pk,err := x509.ParsePKIXPublicKey(pkBlock.Bytes)
(3)证书解析
先解析pem文件,
certBlock,_ := pem.Decode(certBytes)
再解析证书,
cert,err := x509.ParseCertificate(certBlock.Bytes)
(4)完整代码
package main
import (
"crypto/ecdsa"
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"time"
func handleError(err error) {
if err != nil {
panic(err)
func main() {
//公钥解析
fmt.Println("================解析公钥================")
pkFile,err := os.Open("./ecpublic.pem")
handleError(err)
fileinfo,err = pkFile.Stat()
handleError(err)
pkBytes := make([]byte,fileinfo.Size())
n,err = pkFile.Read(pkBytes)
handleError(err)
fmt.Printf("公钥文件内容为:\n%s\n",pkBytes[:n])
//解析pem文件
pkBlock,_ := pem.Decode(pkBytes)
//解析公钥
pk,err := x509.ParsePKIXPublicKey(pkBlock.Bytes)
handleError(err)
switch pub := pk.(type) {
case *ecdsa.PublicKey:
fmt.Printf("ecdsa公钥X:%d\n",pub.X)
fmt.Printf("公钥X长度:%d bit\n",pub.X.BitLen())
default:
panic("公钥解析错误!")
pkFile.Close()
fmt.Println("================解析公钥成功!================")
time.Sleep(1*time.Second)
fmt.Println()
//证书解析
fmt.Println("================解析证书================")
certFile,err := os.Open("./eccert.crt")
handleError(err)
fileinfo,err = certFile.Stat()
handleError(err)
certBytes := make([]byte,fileinfo.Size())
n,err = certFile.Read(certBytes)
handleError(err)
fmt.Printf("证书内容为:\n%s\n",certBytes[:n])
//解析pem文件
certBlock,_ := pem.Decode(certBytes)
//解析证书
cert,err := x509.ParseCertificate(certBlock.Bytes)
handleError(err)
fmt.Println(cert.Issuer)
switch pub := cert.PublicKey.(type) {
case *ecdsa.PublicKey:
fmt.Printf("ecdsa公钥X:%d\n",pub.X)
fmt.Printf("公钥X长度:%d bit\n",pub.X.BitLen())
default: