如何创建证书链
How to create a certificate chain
我正在研究用于自动化浏览器集成测试的代理服务器。我已经到了可以创建根 CA 证书然后创建自签名证书的地方。
但是,我失败的地方是 "joining" 将这些一起放入一个有效的证书链中,然后提供该证书链。我觉得我错过了一些非常微不足道的东西,因为 CA 是正确创建的,自签名证书是由 CA 签名的,但是在浏览器中查看生成的证书时,证书链从不显示 CA。
我意识到这是一个有点神秘的问题,但请告诉我如何才能更清楚地说明这一点。
谢谢大家!
func Server(cn net.Conn, p ServerParam) *ServerConn {
conf := new(tls.Config)
if p.TLSConfig != nil {
*conf = *p.TLSConfig
}
sc := new(ServerConn)
// this is the CA certificate that is performing the signing and I had though would show as the "root" certificate in the chain
conf.RootCAs = buildBoolFromCA(p.CA)
conf.GetCertificate = func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
sc.ServerName = hello.ServerName
// the self signed cert that is generated (the root CA however is not part of the chain
return getCert(p.CA, hello.ServerName)
}
sc.Conn = tls.Server(cn, conf)
return sc
}
为了减小这个 post 的大小,我在这里创建了一个小要点来显示我在哪里生成 CA 和自签名证书:https://gist.github.com/jredl-va/d5df26877fc85095115731d98ea5ff33
更新 1
添加了获取证书到要点
Go 不会神奇地将 CA 证书包含在 TLS 握手中。如果您认为 RootCA 会导致这种情况,那您就错了。与服务器无关:
RootCAs defines the set of root certificate authorities that clients use when verifying server certificates.
您可以将 GenerateCert 更改为 return 整个链:
--- cert.go.orig 2019-09-18 17:35:29.408807334 +0200
+++ cert.go 2019-09-18 17:35:45.028779955 +0200
@@ -46,11 +46,11 @@
x, err := x509.CreateCertificate(rand.Reader, template, ca.Leaf, key.Public(), ca.PrivateKey)
if err != nil {
return nil, err
}
cert := new(tls.Certificate)
- cert.Certificate = append(cert.Certificate, x)
+ cert.Certificate = append(cert.Certificate, x, ca.Leaf.Raw)
cert.PrivateKey = key
cert.Leaf, _ = x509.ParseCertificate(x)
return cert, nil
}
...或让 getCert 以类似的方式附加 CA 证书:
--- cert.go.orig 2019-09-18 18:07:45.924405370 +0200
+++ cert.go 2019-09-18 18:08:11.998359456 +0200
@@ -61,7 +61,8 @@
func getCert(ca *tls.Certificate, host string) (*tls.Certificate, error) {
cert, err := GenerateCert(ca, host)
if err != nil {
return nil, err
}
+ cert.Certificate = append(cert.Certificate, ca.Leaf.Raw)
return cert, nil
}
我正在研究用于自动化浏览器集成测试的代理服务器。我已经到了可以创建根 CA 证书然后创建自签名证书的地方。
但是,我失败的地方是 "joining" 将这些一起放入一个有效的证书链中,然后提供该证书链。我觉得我错过了一些非常微不足道的东西,因为 CA 是正确创建的,自签名证书是由 CA 签名的,但是在浏览器中查看生成的证书时,证书链从不显示 CA。
我意识到这是一个有点神秘的问题,但请告诉我如何才能更清楚地说明这一点。
谢谢大家!
func Server(cn net.Conn, p ServerParam) *ServerConn {
conf := new(tls.Config)
if p.TLSConfig != nil {
*conf = *p.TLSConfig
}
sc := new(ServerConn)
// this is the CA certificate that is performing the signing and I had though would show as the "root" certificate in the chain
conf.RootCAs = buildBoolFromCA(p.CA)
conf.GetCertificate = func(hello *tls.ClientHelloInfo) (*tls.Certificate, error) {
sc.ServerName = hello.ServerName
// the self signed cert that is generated (the root CA however is not part of the chain
return getCert(p.CA, hello.ServerName)
}
sc.Conn = tls.Server(cn, conf)
return sc
}
为了减小这个 post 的大小,我在这里创建了一个小要点来显示我在哪里生成 CA 和自签名证书:https://gist.github.com/jredl-va/d5df26877fc85095115731d98ea5ff33
更新 1 添加了获取证书到要点
Go 不会神奇地将 CA 证书包含在 TLS 握手中。如果您认为 RootCA 会导致这种情况,那您就错了。与服务器无关:
RootCAs defines the set of root certificate authorities that clients use when verifying server certificates.
您可以将 GenerateCert 更改为 return 整个链:
--- cert.go.orig 2019-09-18 17:35:29.408807334 +0200
+++ cert.go 2019-09-18 17:35:45.028779955 +0200
@@ -46,11 +46,11 @@
x, err := x509.CreateCertificate(rand.Reader, template, ca.Leaf, key.Public(), ca.PrivateKey)
if err != nil {
return nil, err
}
cert := new(tls.Certificate)
- cert.Certificate = append(cert.Certificate, x)
+ cert.Certificate = append(cert.Certificate, x, ca.Leaf.Raw)
cert.PrivateKey = key
cert.Leaf, _ = x509.ParseCertificate(x)
return cert, nil
}
...或让 getCert 以类似的方式附加 CA 证书:
--- cert.go.orig 2019-09-18 18:07:45.924405370 +0200
+++ cert.go 2019-09-18 18:08:11.998359456 +0200
@@ -61,7 +61,8 @@
func getCert(ca *tls.Certificate, host string) (*tls.Certificate, error) {
cert, err := GenerateCert(ca, host)
if err != nil {
return nil, err
}
+ cert.Certificate = append(cert.Certificate, ca.Leaf.Raw)
return cert, nil
}