【发布时间】:2017-03-07 07:58:35
【问题描述】:
我想使用 TLS 相互身份验证在 go 中创建的 API 上对客户端进行身份验证。我创建了一个证书颁发机构,假设 Bob 有一个他想与客户端一起使用的密钥对。 Bob 创建了一个证书请求,并希望我验证他的证书以便获得授权和 在 API 上进行身份验证。
我用它来创建我的证书颁发机构:
openssl genrsa -aes256 -out ca.key 4096
openssl req -new -x509 -sha256 -days 730 -key ca.key -out ca.crt
Bob 用它来创建他的证书和证书请求:
openssl genrsa -out bob.key 4096
openssl req -new -key bob.key -out bob.csr
我想实现这一点,但在进行中:
openssl x509 -req -days 365 -sha256 -in bob.csr -CA ca.crt -CAkey ca.key -set_serial 3 -out bob.crt
现在,通过这些命令,Bob 可以创建一个到我的 API 的 TLS 连接,它使用这个 tls.Config :
func createTLSConfig(certFile string, keyFile string, clientCAFilepath string) (config *tls.Config, err error) {
cer, err := tls.LoadX509KeyPair(certFile, keyFile)
if err != nil {
return nil, err
}
clientCAFile, err := ioutil.ReadFile(clientCAFilepath)
if err != nil {
return nil, err
}
clientCAPool := x509.NewCertPool()
clientCAPool.AppendCertsFromPEM(clientCAFile)
config = &tls.Config{
Certificates: []tls.Certificate{cer},
ClientAuth: tls.RequireAndVerifyClientCert,
ClientCAs: clientCAPool,
CipherSuites: []uint16{
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
},
PreferServerCipherSuites: true,
SessionTicketsDisabled: false,
MinVersion: tls.VersionTLS12,
CurvePreferences: []tls.CurveID{tls.CurveP521, tls.CurveP384},
}
return config, nil
}
但是如果 Julia 现在想登录呢?她必须创建一个 CSR,将其发送给我,我也必须手动将她的 CSR 验证到 CRT。为了避免这种手动操作,我们的想法是有一个注册端点,Julia 可以在其中提交她的 CSR 并取回有效的 CRT。端点基本上看起来像这样:
func Register(c echo.Context) (err error) {
// get Julia's csr from POST body
csr := certificateFromBody(c.Body)
// valid csr with ca to generate the crt
crt := signCSR(csr, config.ClientCAPath)
// return the crt to julia
return c.JSON(http.StatusCreated, base64.StdEncoding.EncodeToString(crt))
}
我花了一些时间了解 openssl 如何使用 CA 从 CRS 创建 CRT,但没有成功。
Golang 有一个来自crypto/x509 包的CertificateRequest object,我可以使用ParseCertificateRequest 创建它,但我找不到接受这个对象和我的CA 并返回证书的函数。
感谢您的帮助!
【问题讨论】:
标签: go x509certificate tls1.2 pki mutual-authentication