X.509数字证书标准
X.509 数字证书结构图
简单来说,数字证书就是一张附带了数字签名的信息表。
以RSA算法为例
X.509证书和私钥生成
生成秘钥流程
- 使用
crypto/rsa
中的GenerateKey(random io.Reader, bits int)
方法生成私钥(结构体)
- 因为X509证书采用了ASN1描述结构,需要通过Go语言API将的到的私钥(结构体),转换为
BER
编码规则的字符串。
- 需要将ASN1 BER 规则转回为PEM数据编码。
pem.Encode(out io.Writer, b *Block)
- 将返回的数据保存
生成证书流程
- 使用
crypto/rsa
中的GenerateKey(random io.Reader, bits int)
方法生成私钥(结构体)
- 构建x.509的证书的结构模型
template
- 根据公钥、私钥、证书模板生成DER编码规则的字符串。
- 需要生成的DER编码转回为PEM数据编码。
pem.Encode(out io.Writer, b *Block)
- 将返回的数据保存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| func TestX509Gen(t *testing.T) { max := new(big.Int).Lsh(big.NewInt(1),128) serialNumber, _ := rand.Int(rand.Reader, max) subject := pkix.Name{ Organization: []string{"Manning Publications Co."}, OrganizationalUnit: []string{"Books"}, CommonName: "Go Web Programming", } template := x509.Certificate{ SerialNumber: serialNumber, Subject: subject, NotBefore: time.Now(), NotAfter: time.Now().Add(365 * 24 *time.Hour), KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, IPAddresses: []net.IP{net.ParseIP("127.0.0.1")}, } pk, _ := rsa.GenerateKey(rand.Reader, 2048)
derBytes, _ := x509.CreateCertificate(rand.Reader, &template, &template, &pk.PublicKey, pk) certOut, _ := os.Create("cert.pem") pem.Encode(certOut,&pem.Block{Type:"CERTIFICAET", Bytes: derBytes}) certOut.Close() keyOut, _ := os.Create("key.pem") pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(pk)}) keyOut.Close() }
|
X.509证书解析验证
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| func TestX509CertRead(t *testing.T) { file, _ := ioutil.ReadFile("cert.pem") certBlock, _ := pem.Decode(file) cert, _ := x509.ParseCertificate(certBlock.Bytes) fmt.Println(cert.Version) fmt.Println(cert.Subject.CommonName)
err := cert.CheckSignature(cert.SignatureAlgorithm, cert.RawTBSCertificate, cert.Signature) if err == nil{ println("succeed") }else { println("failed") } println(cert.PublicKey.(*rsa.PublicKey).N.String()) }
|
X.509证书解析私钥
1 2 3 4 5 6 7 8 9 10 11
| func TestSKRead(t *testing.T) { readFile, _ := ioutil.ReadFile("key.pem") pemBlock, _ := pem.Decode(readFile)
privateStream, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes) if err != nil { return }
println(privateStream.PublicKey.N.String()) }
|
参考:
百度百科