证书固定(Certificate pinning)用于许可证分发的公钥私钥方案问询
问题解答
1. 如何从证书中正确读取并验证公钥?
根据你的技术栈场景,分命令行调试和代码实现两种方式:
- 命令行调试场景(验证证书公钥与原私钥是否匹配)
提取证书公钥的命令:
校验公钥一致性:分别计算原私钥导出的公钥哈希、证书提取的公钥哈希,两者输出一致即代表匹配:openssl x509 -in root_cert.pem -pubkey -noout > cert_pubkey.pem# 原私钥导出公钥的哈希 openssl rsa -in private_key.pem -pubout -outform pem | sha256sum # 证书提取公钥的哈希 openssl x509 -in root_cert.pem -pubkey -noout -outform pem | sha256sum - Go代码实现场景(业务逻辑中读取公钥)
你可以直接解析硬编码到代码中的自签名根证书,示例代码如下:
拿到返回的公钥后,直接代入你现有的import ( "crypto/rsa" "crypto/x509" "encoding/pem" "errors" ) // 替换为你自己生成的根证书PEM内容,直接硬编码到代码中 const embeddedRootCert = `-----BEGIN CERTIFICATE----- MIID......你自己的证书内容...... -----END CERTIFICATE-----` func GetValidatedPublicKey() (*rsa.PublicKey, error) { // 解析PEM格式证书 block, _ := pem.Decode([]byte(embeddedRootCert)) if block == nil || block.Type != "CERTIFICATE" { return nil, errors.New("无效的证书PEM格式") } // 解析证书结构体 cert, err := x509.ParseCertificate(block.Bytes) if err != nil { return nil, err } // 校验公钥类型是否为RSA(与你生成的密钥对类型一致) rsaPub, ok := cert.PublicKey.(*rsa.PublicKey) if !ok { return nil, errors.New("证书公钥不是RSA类型") } // 校验证书是否为合法的自签名根证书(避免篡改) if err = cert.CheckSignatureFrom(cert); err != nil { return nil, errors.New("证书签名校验失败,非合法自签名根证书") } // 可选:额外校验证书有效期、主题等自定义字段,进一步防篡改 return rsaPub, nil }VerifyAndExtractPayload方法即可正常完成许可证校验。
注意:你之前操作步骤里写的「将私钥嵌入代码」是严重错误,私钥只能保存在你自己生成许可证的受控环境中,绝对不能嵌入到分发的客户端代码里,泄露私钥会导致所有人都可以伪造合法许可证。
2. 通过该方式获取的公钥是否已完成来源合法性验证?
只要满足两个前提,该公钥就已经完成了来源合法性验证,可以直接信任:
- 你硬编码到代码中的根证书是你自己生成的官方证书,编译前可以通过哈希校验确保证书没有被篡改
- 代码中加上了上面示例中的自签名校验逻辑,确保证书内容未被修改
你采用的是证书固定方案,没有依赖第三方CA信任链,证书本身是直接编译到应用二进制中的,不存在外部加载、网络传输等被篡改的路径,所以只要你内嵌的证书本身是合法的,解析出来的公钥就无需再做额外的来源校验。
内容的提问来源于stack exchange,提问作者Chris G.
相关产品推荐
相关产品推荐

