我的用例看起来像我知道客户的公共证书,并且只希望允许它们。我有一个基于gin和TLS配置的go服务器,其中已为属性“ VerifyPeerCertificate”分配了一个方法。 该功能看起来像
func customVerifyPeerCertificate(rawCerts [][]byte, verifiedChains [][]*x509.Certificate) error {
if len(verifiedChains) < 1 {
return errors.New("Verified certificate chains is empty.")
}
if len(verifiedChains[0]) < 1 {
return errors.New("No certificates in certificate chains.")
}
if len(verifiedChains[0][0].Subject.CommonName) < 1 {
return errors.New("Common name can not be empty.")
}
fmt.Println(verifiedChains[0][0].Raw)
publicKeyDer, _ := x509.MarshalPKIXPublicKey(verifiedChains[0][0].PublicKey)
publicKeyBlock := pem.Block{
Type: "CERTIFICATE",
Bytes: publicKeyDer,
}
publicKeyPem := string(pem.EncodeToMemory(&publicKeyBlock))
}
但是,问题是,变量“ publicKeyPem”中的字符串看起来不像我用来将请求发送到服务器的客户端公共证书,而且长度也较短。
答案 0 :(得分:0)
证书不仅仅是其公钥。整个x509.Certificate对象代表客户端提供的证书,公共密钥字段仅是公共密钥的实际值。
如果要比较证书的严格相等性,则应使用传递给回调的rawCerts [][]byte
参数。在VerifyPeerCertificate
的{{3}}注释中提到了这一点:
VerifyPeerCertificate, if not nil, is called after normal
certificate verification by either a TLS client or server. It
receives the raw ASN.1 certificates provided by the peer and also
any verified chains that normal processing found. If it returns a
non-nil error, the handshake is aborted and that error results.
答案 1 :(得分:0)
感谢Marc,我知道我使用了错误的变量。要将证书转换为客户端使用的字符串,请使用以下代码
publicKeyBlock := pem.Block{
Type: "CERTIFICATE",
Bytes: rawCerts[0],
}
publicKeyPem := string(pem.EncodeToMemory(&publicKeyBlock))