Golang生成SSL证书以及服务器私钥

4 minute read

SSL 证书X.509 是国际电信联盟电信标准化部门( ITU-T )为公钥基础设施制定的一个标准,这个标准包含了公钥证书的标准格式。 一个 X.509 证书(简称 SSL 证书)实际上就是一个经过编码的 ASN.1( Abstract Syntax Notation One,抽象语法表示法/1 )格式的电子文档。 ASN.1 既是一个标准,也是一种表示法,它描述了表示电信以及 计算机网络数据的规则和结构。

X.509 证书可以使用多种格式编码,其中一种编码格式是 BER ( Basic Encoding Rules ,基本编码规 则)。 BER 格式指定了一种自解释并且自定义的格式用于对 ASN.1 数据结构进行编码,而 DER 格式则是 BER 的一个子集。 DER 只提供了一种编码 ASN.1 值的方法,这种方法被广泛地应用于密码学当中,尤其是对 X.509 证书进行加密。56 第 3 章接收请求SSL 证书可以以多种不同的格式保存,其中一种是 PEM (Privacy Enhanced Email ,隐私增强邮件 )格式,这种格式会对 DER 格式的 X.509 证书实施Base64 编码,并且这种格式的文件都以一一BEGINCERTIFICATE一开头,以一一END CERTIF工CATE一结尾{除了用作文件格式之外 , PEM和此处讨论的 SSL 证书关系并不大)。

生成证书的方法并不复杂,因为 SSL 证书实际上就是一个将扩展密钥用 法(extended key usage)设置成了服务器身份验证操作的X.509证书

配置证书信息

 1//生成一个比较长的随机整数来做序列号
 2max := new(big.Int).Lsh(big.NewInt(1), 128)
 3seriaNumber := rand.Int(rand.Reader, max)
 4//生成证书标题
 5subject := pkix.Name{
 6		Organization:       []string{"Mu1er.cn"},
 7		OrganizationalUnit: []string{"mu1er"},
 8		CommonName:         "mu1er.cn",
 9	}
10template := x509.Certificate{
11		SerialNumber: seriaNumber,
12		Subject:      subject,
13		NotBefore:    time.Now(),
14        //有效期
15		NotAfter:     time.Now().Add(365 * 24 * time.Hour),
16        //用x509证书来验证
17		KeyUsage:     x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
18		ExtKeyUsage:  []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
19        //运行地址
20		IPAddresses:  []net.IP{net.ParseIP("127.0.0.1")},
21	}

生成 RSA 私钥

1pk, _ := rsa.GenerateKey(rand.Reader, 2048)

私钥结构里面包含了一个能够公开访问的公钥,随后创建SSL证书的时候会用到

1derBytes, _ := x509.CreateCertificate(rand.Reader, &template, &template,&pk.PublicKey, pk)

CreateCertificate函数接受Certificate结构、公钥和私钥等多个参数,创建出一个经过 DER 编码格式化的字节切片 。后续代码的意图也非常简单明了,它们首先使用encoding/pem标准库将证书编码到cert.pem文件里面

1certOut, _ := os.Create("cert.pem")
2pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
3certOut.Close()

然后继续以 PEM 编码的方式把之前生成的密钥编码并保存到key.pem文件里面:

1keyOut, _ := os.Create("key.pem")
2pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(pk)})
3keyOut.Close()

最后需要提醒的是,如果证书是由CA签发的,那么证书文件中将同时包含服务器签名以及CA签名,其中服务器签名在前,CA签名在后.