相关文章推荐
小百科  ›  go语言怎么加载加密后的pkcs8密钥和证书? - 小明 的回答 -
openssl生成证书 公钥加密 pem 公钥算法
性感的饼干
2 年前
go语言怎么加载加密后的pkcs8密钥和证书?
小明
小明
密码学业余选手

要想知道怎么加载密钥和证书,首先要知道现有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:
 
推荐文章
Link管理   ·   Sov5搜索   ·   小百科
小百科 - 百科知识指南