x509证书
1. 概述
X.509标准是密码学里公钥证书的格式标准。X.509 证书己应用在包括TLS/SSL(WWW万维网安全浏览的基石)在内的众多 Internet协议里,同时它也有很多非在线的应用场景,比如电子签名服务。X.509证书含有公钥和标识(主机名、组织或个人),并由证书颁发机构(CA)签名(或自签名)。对于一份经由可信的证书签发机构签名(或者可以通过其它方式验证)的证书,证书的拥有者就可以用证书及相应的私钥来创建安全的通信,以及对文档进行数字签名。
2. x509证书结构
X.509证书的结构是用ASN.1(Abstract Syntax Notation One:抽象语法标记)来描述其数据结构,并使用ASN1语法进行编码。
X.509 v3数字证书的结构如下:
-
Certificate 证书内容
-
Version 证书版本号,版本(version)为整数格式。证书格式的版本只有v1、v2、v3,分别用整数0、1、2表示
-
Serial Number 证书序列号,RFC 3280标准要求证书序列号必须是正整数,且长度不应该大于20字节
-
Signature Algorithm CA签发证书时所使用的数字签名算法
-
Issuer 签发证书的CA实体
-
Validity 证书有效期
-
Not Before 证书起始日期
-
Not After 证书截至日期
-
Subject 证书持有者实体
-
Subject Pbulic Key Info 证书持有者公钥信息
-
Public Key Algorithm 证书持有者公钥算法
-
Public-Key 证书持有者公钥信息
-
Issuer Unique Identifier (optional)颁发者唯一标识符(可选)
-
Subject Unique Identifier (optional)主题唯一标识符(可选)
-
X509v3 extensions (optional) 证书的扩展项(可选)
-
Sigature Algorithm CA签发证书时所使用的数字签名算法
-
Signature 证书的签名
openssl x509 -in secp256k1cert.pem -noout -text Certificate: Data: Version: 3 (0x2) Serial Number: 3a:15:11:3c:1a:74:77:6d:ff:5f:b6:8f:28:e7:83:73 Signature Algorithm: ecdsa-with-SHA256 Issuer: C=CN, ST=BJ, L=BJ, O=youngz, OU=youngz, CN=hello.world.com Validity Not Before: Mar 19 12:26:16 2022 GMT Not After : Mar 19 12:26:00 2023 GMT Subject: C=CN, ST=BJ, L=BJ, O=youngz, OU=youngz, CN=hello.world.com Subject Public Key Info: Public Key Algorithm: id-ecPublicKey Public-Key: (256 bit) pub: 04:73:c5:fc:f3:f1:c6:3f:33:bf:d7:f1:c9:e1:f1: 7e:c7:da:4a:80:9b:94:db:44:70:24:8b:b9:1d:ff: 99:ad:81:0f:b7:a7:76:85:21:68:a3:8c:df:87:9f: 58:11:a1:54:a6:91:75:2e:97:85:5b:7e:f6:2b:34: 36:34:c1:65:5f ASN1 OID: secp256k1 X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Certificate Sign X509v3 Extended Key Usage: TLS Web Client Authentication, TLS Web Server Authentication X509v3 Basic Constraints: critical CA:TRUE X509v3 Subject Key Identifier: 30:EF:CB:66:8C:8C:B8:2E:DE:81:4C:D3:35:22:EA:E5:55:45:D5:C4 X509v3 Subject Alternative Name: DNS:hello.world, IP Address:127.0.0.1 Signature Algorithm: ecdsa-with-SHA256 30:45:02:20:05:30:ab:42:40:0a:fb:d4:04:8b:10:22:31:c3: 94:24:9f:03:68:c2:96:a2:7e:f8:c6:86:ff:5d:f0:6d:fa:c6: 02:21:00:8e:53:c3:c6:90:bc:76:68:a4:d9:f8:71:a5:cf:3f: b0:95:b4:20:a6:ca:88:26:88:4b:6b:0d:8d:b4:6f:5a:d8
2.1 证书扩展字段(X509v3 extensions)
2.1.1 Key Usage
- Digital Signature 用于验证数字签名(除了签发证书,签发CRL和非否认性服务)。
- Content Commitment 表示私钥可以用来进行非否认性服务中的签名
- Key Encipherment 密钥用来加密传输其他密钥
- Data Encipherment 公钥用来直接加密数据
- Key Agreement 用于密钥协商时
- Cert Sign 用于验证公钥证书上的签名
- CRL Sign 用于验证证书撤销列表(例如CRL、增量CRL或ARL)上的签名时
- Encipher Only 在没有密钥协商位的情况下,仅加密位的含义未定义。当仅加密位被断言并且密钥协商位也被设置时,主体公钥可仅用于在执行密钥协商时对数据进行加密。
- Decipher Only 在没有密钥协商位的情况下,仅解密位的含义未定义。当仅解密位被断言并且密钥协商位也被设置时,主体公钥可仅用于在执行密钥协商时解密数据。
总结: 如果存在keyUsage扩展,则除非设置了相应的keyCertSign或cRLSign位,否则不得使用subject公钥验证证书或CRL上的签名。如果subject公钥仅用于验证证书和/或CRL上的签名,则不应设置数字签名和非否认位。然而,如果主体公钥将用于验证证书和/或CRL以及其他对象上的签名,则可以在keyCertSign和/或cRLSign位之外设置数字签名和/或非否认位。
2.1.2 Extended Key Usage
- ServerAuth
- ClientAuth
- CodeSigning
- EmailProtection
- IPSECEndSystem
- IPSECTunnel
- IPSECUser
- TimeStamping
- OCSPSigning
- MicrosoftServerGatedCrypto
- NetscapeServerGatedCrypto
2.1.3 Basic Constraints
- 基本限制扩展用来区分该证书是CA证书还是末端实体证书
- CA证书给出最大路径深度,为关键性扩展
- 末端实体证书,关键或非关键扩展
2.1.4 Subject Key Identifier
主体密钥标识:用户会进行不同安全要求的业务,需要多个密钥/证书来对应不同的应用。主体密钥标识的作用:区分用户的各个密钥/证书对,也就是区分各个公钥
2.1.5 Subject Alternative Name
以上扩展用于表示CA/证书主体非X.500 DN形式的身份信息和名称(如IP地址,电子邮件,域名)
3. 证书分类
证书根据用途分类,可以分为三类:根证书,中间证书,实体证书。根证书->中间证书->实体证书,构成了一条证书链。根证书是证书链的起点,实体证书是证书链的重点(也叫末端证书)
3.1 根证书
根证书:所谓根证书就是ca机构自签证书,证书机构用这个自签证书去给其他人签发中间证书
3.2 中间证书
中间证书:中间证书是由可信的ca机构(根证书)签发的子证书,受ca机构的信任。同时中间证书也可以作为新的机构的根证书,去签发下一级的中间证书,或者签发自己的实体证书
3.3 实体证书
实体证书:实体证书是由中间证书签发的子证书(基本由中间证书签发,也可以由根证书签发<不建议用根证书签发实体证书,减少根证书的对外的暴露>)
4. 证书的输出格式
.der
用于二进制DER编码证书
.pem
用于不同类型的X.509v3文件,是以"- BEGIN …"前缀的ASCII(Base64)数据,不止用于证书,还可用于单独的私钥文件
-----BEGIN CERTIFICATE-----
MIICQDCCAeegAwIBAgIRAMz//txip7OCd/RPFj70j/QwCgYIKoZIzj0EAwIwYzEL
MAkGA1UEBhMCQ04xCzAJBgNVBAgTAkJKMQswCQYDVQQHEwJCSjEPMA0GA1UEChMG
eW91bmd6MQ8wDQYDVQQLEwZ5b3VuZ3oxGDAWBgNVBAMTD2hlbGxvLndvcmxkLmNv
bTAeFw0yMjAzMjAwNzQ5NDNaFw0yMzAzMjAwNzUwMDBaMGMxCzAJBgNVBAYTAkNO
MQswCQYDVQQIEwJCSjELMAkGA1UEBxMCQkoxDzANBgNVBAoTBnlvdW5nejEPMA0G
A1UECxMGeW91bmd6MRgwFgYDVQQDEw9oZWxsby53b3JsZC5jb20wVjAQBgcqhkjO
PQIBBgUrgQQACgNCAAREETkIgjrHWdyxaHWpuNl6o9jrel+isQsS1Z6hWDP32V5y
UNuXDykKIN+wnsZBpCMEYMHb2QHV0jpemJqQp0pFo38wfTAOBgNVHQ8BAf8EBAMC
AoQwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMA8GA1UdEwEB/wQFMAMB
Af8wHQYDVR0OBBYEFMot6y8NPSPzvphQlCVbTpGWtoQLMBwGA1UdEQQVMBOCC2hl
bGxvLndvcmxkhwR/AAABMAoGCCqGSM49BAMCA0cAMEQCIC+cRTpDwt4f5wyLD+R+
BuZFR7HIveiA5LJwkE2Ua77LAiBDvv0t+lC7TER4ixprWJqyef2upuO8j/pCzJIZ
mqmwuA==
-----END CERTIFICATE-----
.crt
用于证书,可以采用二进制DER或ASCII PEM编码,Unix 或类Unix系统中常见,CER和CRT扩展几乎是同义词
.cer
crt的替代形式,macrosoft的转换形式
.key
用于公钥和私钥PKCS#8,可以被编码为二进制DER或ASCII PEM
-----BEGIN EC PRIVATE KEY-----
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgOpA43TnovcOtCeiLBPqn
VNgfO4Hi/Ept9v0TxuBSgb6hRANCAARFrCbbwVIRn6ottQLNxjTFJhQYCybnzn0j
RAsl10eez0S2GlSLQ87yzRLycQE/I9yjk1h62t7IZ6FQ1elP5saE
-----END EC PRIVATE KEY-----
.p7b, .p7c
– PKCS#7 SignedData structure without data, just certificate(s) or CRL(s)
.p12
– PKCS#12格式,包含证书的同时可能还有带密码保护的私钥
.pfx – PFX
,PKCS#12 之前的格式(通常用 PKCS#12 格式,比如那些由IIS产生的 PFX 文件)
5. 证书吊销
在证书有效期中间,该证书可能无效,如:私钥丢失身份信息发生变化。应该阻止订户停止使用该证书,CA要撤销该证书。Certificate Revocation List证书撤销列表也要CA进行数字签名,以实现数据完整性、数据源鉴别、非否认。
证书吊销列表 (CRL,见RFC5280) 提供已吊销的证书的列表。客户端应用程序(如 Web 浏览器)可以使用 CRL 检查服务器的真实性。服务器应用程序(如Apache或OpenV.P.N)可以使用 CRL 拒绝访问不再受信任的客户端。在公共可访问的位置(例如http://example.com/intermediate.crl.pem)发布 CRL,第三方可以从此位置获取 CRL,以检查他们依赖的证书是否已被吊销。由于CRL的更新是有周期的,所以在证书已经被撤销,但是CRL还没有更新的情况下就无法查询到最新状态,此时应该使用ocsp来进行实时的查询。
6. OpenSSL使用
6.1 生成公私钥
6.1.1生成rsa公私钥
# 1. 生成私钥
openssl genrsa -out rsaprivatekey.pem 512
-----BEGIN RSA PRIVATE KEY-----
MIIBOgIBAAJBAJbxkv3G8IEluvPwUtuVbRm9dn88DW2jbc1IP0lHZUXc9t0romf0
wyyMmrnm9GcmjIZKtlsYwnqUQ0q84xXH/2UCAwEAAQJAF6WSzJUM+n6JskuU/3eC
VwT6emZTCDkRK5bE61r2/6GnpV8U616VVcG/p8PWQG7Nc54yZ2hpTkbB+GiD8d9Y
BQIhAMfWDqkukbwxxJs4LeTIsg56DDf2eJBi3Itw8MErBQZfAiEAwV3EOar/68SS
dDYPYgt9vvDzKrLZYIcsFIb6hr3SqLsCIBd8KqDrXik12Bs90PbwNyzIXyM8jhK5
651fmou5GJAVAiEAhCD8aqNsSMCDiqE+FbLgc87VekHHw+vZtRUer1+aSO0CIEk9
+USV3jvtPIPVg+N+ZwCDG/hsm5kYtQt9COQP1uCe
-----END RSA PRIVATE KEY-----
# 2. 生成公钥(从私钥中提取公钥)
openssl rsa -pubout -in rsaprivatekey.pem -out rsapublickey.pem
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJbxkv3G8IEluvPwUtuVbRm9dn88DW2j
bc1IP0lHZUXc9t0romf0wyyMmrnm9GcmjIZKtlsYwnqUQ0q84xXH/2UCAwEAAQ==
-----END PUBLIC KEY-----
# 3. 生成带口令的私钥
openssl genrsa -out rsaprivatekey.pem -passout pass:123456 -des3 512
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,9A5FDC2856B53E72
elBPfcBzR6haOU9rm38edA1eleEEMKVCpcRBwUaZf/sOV/Bfg78U7f0tL235BVtS
zYQOZq+bPXjL7qkC6iE+Z+nuM5fEjL3WzbqfnDaUYqtr6FC6YGX/wG38ky8tSFev
D29KiRqaldnk5yrAp0gBoWvZfm78zC8CGLh65meSjbZ3vVZFXiN8qM7jVNS730sS
gACB5nXZE22l7WFPZkuOT0Q3/2KkibIbZ00TcZIC2dfZrDdU5CIlvMYWg7YRSyZX
R4TDVF4tCKxdYpQt6/iv9zlTMXIJSIfIrTDkpQRdxSq48q5/NeqohuLdDSHBdpcW
RfRmUld8ztpzeNyMubuJMx7W+EofYiSALIWYF73gnAvGlKJRs5sPNXsBT1HAxT37
A0rIE5/PpEQ5+Rr4Ym9S4aenAOp+ZLa+k2iXrBd0V1jwYneTa/+Raw==
-----END RSA PRIVATE KEY-----
# 4. 从带口令的私钥中提取公钥
openssl rsa -in rsaprivatekey.pem -passin pass:123456 -pubout -out rsapublickey.pem
-----BEGIN PUBLIC KEY-----
MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAMBUYc9XgABebGvp2CdrMIXw1uFHJ9eG
1nwrtFZ066tAxybj6uyizLB5pQQ03awvW7DFzZEiX2KNPQda7b1pTucCAwEAAQ==
-----END PUBLIC KEY-----
# 5. 查看带口令的私钥
openssl rsa -in rsaprivatekey.pem -noout -text -passin pass:123456
6.1.2生成ecc公私钥
# 1. 生成secp256k1私钥
openssl ecparam -genkey -name secp256k1 -out secp256k1pk.key
-----BEGIN EC PARAMETERS-----
BgUrgQQACg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIFTX9EtiHqskcT6G3Uv2Fts9DhUuN0suWkaLIPYXWa+HoAcGBSuBBAAK
oUQDQgAEZWBanwDMoEhCdBY17yeBqw+Kiw7WXllmh+x74w2+oYV9adQxVXsDi4FN
gQ3c8DwAR/VMakcKp6kuOTEjnpAfmg==
-----END EC PRIVATE KEY-----
# 2. 转成pkcs8格式
openssl pkcs8 -topk8 -in secp256k1pk.key -out secp256k1pk.p8 -nocrypt
-----BEGIN PRIVATE KEY-----
MIGEAgEAMBAGByqGSM49AgEGBSuBBAAKBG0wawIBAQQgVNf0S2IeqyRxPobdS/YW
2z0OFS43Sy5aRosg9hdZr4ehRANCAARlYFqfAMygSEJ0FjXvJ4GrD4qLDtZeWWaH
7HvjDb6hhX1p1DFVewOLgU2BDdzwPABH9UxqRwqnqS45MSOekB+a
-----END PRIVATE KEY-----
# 3. 从私钥里提取公钥
openssl ec -in secp256k1pk.key -pubout -out secp256k1pub.key
-----BEGIN PUBLIC KEY-----
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEZWBanwDMoEhCdBY17yeBqw+Kiw7WXllm
h+x74w2+oYV9adQxVXsDi4FNgQ3c8DwAR/VMakcKp6kuOTEjnpAfmg==
-----END PUBLIC KEY-----
# 4. 将公钥转成16进制
xxd -c 10000000 -ps ./secp256k1pub.key
6.2 生成证书
以下证书算法都是使用secp256k1算法
# 1. 生成根证书私钥
openssl ecparam -genkey -name secp256k1 -out root.key
-----BEGIN EC PARAMETERS-----
BgUrgQQACg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIPC62IBJyL6gsrUGBReZKZyCsj/qtybxvXtjMw89S32aoAcGBSuBBAAK
oUQDQgAEs0Q1vsaw2BjdB6xjiXDG5vodM2M5vk3j2cCA0slIFzVqnbGMEintj9ls
s2mieMuZdssHlJ+T0YHXJWEdKJu9ZQ==
-----END EC PRIVATE KEY-----
# 2. 生成自签名根证书
openssl req -new -x509 -days 365 -key root.key -out root.crt
-----BEGIN CERTIFICATE-----
MIICHTCCAcKgAwIBAgIUcs/MwDHYIK0dAdQQ+PB7YlQ/BPkwCgYIKoZIzj0EAwIw
ZTELMAkGA1UEBhMCQkoxCzAJBgNVBAgMAkJqMQswCQYDVQQHDAJCSjEQMA4GA1UE
CgwHY29tcGFueTEQMA4GA1UECwwHc2VjdGlvbjEYMBYGA1UEAwwPaGVsbG8ud29y
bGQuY29tMB4XDTIyMDMyMDE1NDEwN1oXDTIzMDMyMDE1NDEwN1owZTELMAkGA1UE
BhMCQkoxCzAJBgNVBAgMAkJqMQswCQYDVQQHDAJCSjEQMA4GA1UECgwHY29tcGFu
eTEQMA4GA1UECwwHc2VjdGlvbjEYMBYGA1UEAwwPaGVsbG8ud29ybGQuY29tMFYw
EAYHKoZIzj0CAQYFK4EEAAoDQgAEs0Q1vsaw2BjdB6xjiXDG5vodM2M5vk3j2cCA
0slIFzVqnbGMEintj9lss2mieMuZdssHlJ+T0YHXJWEdKJu9ZaNTMFEwHQYDVR0O
BBYEFF4SScwUWfDNqviiolTtOfZ3LFKPMB8GA1UdIwQYMBaAFF4SScwUWfDNqvii
olTtOfZ3LFKPMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZIzj0EAwIDSQAwRgIhAM7x
MNgybzW2lI7aa7vpAiXGRs25UX9TtyTM/3+8Th8IAiEA9KBKeWF2SyW+MUbIjM7s
BGk7Sdu2Wog3AIVwsKm3FSY=
-----END CERTIFICATE-----
# 3. 生成子证书私钥
openssl ecparam -genkey -name secp256k1 -out child.key
-----BEGIN EC PARAMETERS-----
BgUrgQQACg==
-----END EC PARAMETERS-----
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIJPXq0OVpGea8hSioBcNW1J5+8r4uP0d+/lb+dfuiObWoAcGBSuBBAAK
oUQDQgAEB+Q6FrDNZgTCCDFkZz4O+tIjVqBo+lhRJdiTiw3C7DD8sDJVbu/3ml1f
bVdnUXtIrRDVsHYdAzV7nd2fR7trTQ==
-----END EC PRIVATE KEY-----
# 4. 生成子证书请求文件
openssl req -new -key child.key -out child.csr
-----BEGIN CERTIFICATE REQUEST-----
MIIBHTCBxQIBADBmMQswCQYDVQQGEwJCSjELMAkGA1UECAwCQkoxCzAJBgNVBAcM
AkJKMREwDwYDVQQKDAhjb21wYW55MTERMA8GA1UECwwIc2VjdGlvbjExFzAVBgNV
BAMMDmhlbGxvLndvcmxkLmNuMFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEB+Q6FrDN
ZgTCCDFkZz4O+tIjVqBo+lhRJdiTiw3C7DD8sDJVbu/3ml1fbVdnUXtIrRDVsHYd
AzV7nd2fR7trTaAAMAoGCCqGSM49BAMCA0cAMEQCIFYoDrwqS4qtiMsh0QsoGdDL
953i2y4Oz+lsSGlli4ucAiBz5pLD/IpTMfkA+pB1Fi/Z6xHiqJSFJ9jKa1ZwAwfi
tw==
-----END CERTIFICATE REQUEST-----
# 5. 使用根证书签发子证书
openssl x509 -req -in child.csr -out child.crt -CA root.crt -CAkey root.key -CAcreateserial
-----BEGIN CERTIFICATE-----
MIIBwzCCAWkCFBV2qyP5KfhOQ32q8PwUjGME46wWMAoGCCqGSM49BAMCMGUxCzAJ
BgNVBAYTAkJKMQswCQYDVQQIDAJCajELMAkGA1UEBwwCQkoxEDAOBgNVBAoMB2Nv
bXBhbnkxEDAOBgNVBAsMB3NlY3Rpb24xGDAWBgNVBAMMD2hlbGxvLndvcmxkLmNv
bTAeFw0yMjAzMjAxNTUxNDRaFw0yMjA0MTkxNTUxNDRaMGYxCzAJBgNVBAYTAkJK
MQswCQYDVQQIDAJCSjELMAkGA1UEBwwCQkoxETAPBgNVBAoMCGNvbXBhbnkxMREw
DwYDVQQLDAhzZWN0aW9uMTEXMBUGA1UEAwwOaGVsbG8ud29ybGQuY24wVjAQBgcq
hkjOPQIBBgUrgQQACgNCAAQH5DoWsM1mBMIIMWRnPg760iNWoGj6WFEl2JOLDcLs
MPywMlVu7/eaXV9tV2dRe0itENWwdh0DNXud3Z9Hu2tNMAoGCCqGSM49BAMCA0gA
MEUCIA8LypbB/axp3QsZFJKd+nw+jILR5WSj8PvJ7T5m2aMEAiEA8Xj5eMBBgO7E
wptXl+3ontoG76+WVFnyU7veQNVhObM=
-----END CERTIFICATE-----
# 6. 验证子证书是否是根证书签发的
openssl verify -verbose -CAfile root.crt child.crt
child.crt: OK
6.3 解析证书私钥
# 1. 查看证书
openssl x509 -in secp256k1cert.pem -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
f5:b0:70:c0:5e:43:cd:6d:6e:62:6b:b7:87:37:1a:df
Signature Algorithm: ecdsa-with-SHA256
Issuer: C=CN, ST=BJ, L=BJ, O=youngz, OU=youngz, CN=hello.world.com
Validity
Not Before: Mar 20 09:29:04 2022 GMT
Not After : Mar 20 09:29:00 2023 GMT
Subject: C=CN, ST=BJ, L=BJ, O=youngz, OU=youngz, CN=hello.world.com
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:45:ac:26:db:c1:52:11:9f:aa:2d:b5:02:cd:c6:
34:c5:26:14:18:0b:26:e7:ce:7d:23:44:0b:25:d7:
47:9e:cf:44:b6:1a:54:8b:43:ce:f2:cd:12:f2:71:
01:3f:23:dc:a3:93:58:7a:da:de:c8:67:a1:50:d5:
e9:4f:e6:c6:84
ASN1 OID: secp256k1
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Certificate Sign
X509v3 Extended Key Usage:
TLS Web Client Authentication, TLS Web Server Authentication
X509v3 Basic Constraints: critical
CA:TRUE
X509v3 Subject Key Identifier:
F3:57:40:A5:E8:81:81:1E:25:27:99:BE:56:6A:86:12:2A:BB:87:91
X509v3 Subject Alternative Name:
DNS:hello.world, IP Address:127.0.0.1
Signature Algorithm: ecdsa-with-SHA256
30:44:02:20:74:79:17:b3:4b:15:a7:b1:bc:bd:74:c0:22:40:
97:5d:ef:9f:f3:2b:7f:29:38:68:cd:be:14:3d:eb:7b:e8:dd:
02:20:4c:84:4e:51:da:ba:f7:cd:a3:79:0b:ee:47:cb:72:ae:
39:1d:c2:08:a4:5a:50:16:9f:96:9a:fe:f9:e9:43:77
# 2. 查看私钥
openssl ec -in secp256k1key.pem -noout -text
read EC key
Private-Key: (256 bit)
priv:
3a:90:38:dd:39:e8:bd:c3:ad:09:e8:8b:04:fa:a7:
54:d8:1f:3b:81:e2:fc:4a:6d:f6:fd:13:c6:e0:52:
81:be
pub:
04:45:ac:26:db:c1:52:11:9f:aa:2d:b5:02:cd:c6:
34:c5:26:14:18:0b:26:e7:ce:7d:23:44:0b:25:d7:
47:9e:cf:44:b6:1a:54:8b:43:ce:f2:cd:12:f2:71:
01:3f:23:dc:a3:93:58:7a:da:de:c8:67:a1:50:d5:
e9:4f:e6:c6:84
ASN1 OID: secp256k1
# 3. 查看证书请求文件
openssl req -in child.csr -noout -text
Certificate Request:
Data:
Version: 1 (0x0)
Subject: C = BJ, ST = BJ, L = BJ, O = company1, OU = section1, CN = hello.world.cn
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:07:e4:3a:16:b0:cd:66:04:c2:08:31:64:67:3e:
0e:fa:d2:23:56:a0:68:fa:58:51:25:d8:93:8b:0d:
c2:ec:30:fc:b0:32:55:6e:ef:f7:9a:5d:5f:6d:57:
67:51:7b:48:ad:10:d5:b0:76:1d:03:35:7b:9d:dd:
9f:47:bb:6b:4d
ASN1 OID: secp256k1
Attributes:
a0:00
Signature Algorithm: ecdsa-with-SHA256
30:44:02:20:56:28:0e:bc:2a:4b:8a:ad:88:cb:21:d1:0b:28:
19:d0:cb:f7:9d:e2:db:2e:0e:cf:e9:6c:48:69:65:8b:8b:9c:
02:20:73:e6:92:c3:fc:8a:53:31:f9:00:fa:90:75:16:2f:d9:
eb:11:e2:a8:94:85:27:d8:ca:6b:56:70:03:07:e2:b7
7. go生成证书
package main
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"os"
"time"
)
func main() {
// 生成公私钥对
caPrivkey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
if err != nil {
panic(err)
}
// 生成证书模板文件
template := newTemplate()
// 生成自签证书(template=parent)
rootCertDer, err := x509.CreateCertificate(rand.Reader, template, template, &caPrivkey.PublicKey, caPrivkey) //DER 格式
if err != nil {
panic(err)
}
// 将私钥编码为pkcs8格式
caPrivBytes, err := x509.MarshalPKCS8PrivateKey(caPrivkey)
if err != nil {
panic(err)
}
// 将私钥转为pem格式
rootKeyFile, err := os.Create("./root.key")
if err != nil {
panic(err)
}
if err = pem.Encode(rootKeyFile, &pem.Block{Type: "EC PRIVATE KEY", Bytes: caPrivBytes}); err != nil {
panic(err)
}
rootKeyFile.Close()
// 将证书转为pem格式
rootCertFile, err := os.Create("./root.crt")
if err != nil {
panic(err)
}
if err = pem.Encode(rootCertFile, &pem.Block{Type: "CERTIFICATE", Bytes: rootCertDer}); err != nil {
panic(err)
}
rootCertFile.Close()
}
func newTemplate() *x509.Certificate {
max := new(big.Int).Lsh(big.NewInt(1), 128) //把 1 左移 128 位,返回给 big.Int
serialNumber, _ := rand.Int(rand.Reader, max) //返回在 [0, max) 区间均匀随机分布的一个随机值
template := &x509.Certificate{
SerialNumber: serialNumber, // SerialNumber 是 CA 颁布的唯一序列号,在此使用一个大随机数来代表它
Subject: pkix.Name{ // 证书的主题信息
Country: []string{"CN"}, // 证书所属的国家
Organization: []string{"company"}, // 证书存放的公司名称
OrganizationalUnit: []string{"department"}, // 证书所属的部门名称
Province: []string{"BeiJing"}, // 证书签发机构所在省
CommonName: "hello.world.com", // 证书域名
Locality: []string{"BeiJing"}, // 证书签发机构所在市
},
NotBefore: time.Now(),
NotAfter: time.Now().AddDate(10, 0, 0),
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth, x509.ExtKeyUsageServerAuth}, // 典型用法是指定叶子证书中的公钥的使用目的。它包括一系列的OID,每一个都指定一种用途。例如{id pkix 31}表示用于服务器端的TLS/SSL连接;{id pkix 34}表示密钥可以用于保护电子邮件。
KeyUsage: x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, // 指定了这份证书包含的公钥可以执行的密码操作,例如只能用于签名,但不能用来加密
IsCA: true, // 指示证书是不是ca证书
BasicConstraintsValid: true, // 指示证书是不是ca证书
}
return template
}
8. 参考文档
https://blog.csdn.net/weixin_43255133/article/details/84025214
https://blog.csdn.net/weixin_38451161/article/details/108180919
https://www.cnblogs.com/f-ck-need-u/p/6091105.html
http://www.rfc2cn.com/rfc5280.html