Go语言中如何可靠解析非压缩格式ECDSA公钥?
可靠的非压缩ECDSA公钥解析方法(Go语言)
你当前的解析函数仅做了字节拆分,没有任何校验逻辑,容易因非法输入导致后续操作出错。针对你接收的04开头的非压缩格式P256 ECDSA公钥,可以通过以下步骤实现可靠解析:
核心校验与解析逻辑
- 校验输入长度:非压缩格式公钥固定为65字节(1字节前缀 + 32字节X坐标 + 32字节Y坐标)
- 校验格式前缀:确认首字节为0x04(非压缩格式标识)
- 验证曲线合法性:检查(X,Y)坐标是否确实落在P256椭圆曲线上
- 暴露错误信息:将解析错误返回给调用方,避免生成非法公钥
完整实现代码
import ( "crypto/ecdsa" "crypto/elliptic" "errors" "math/big" ) func HexToPublicKey(data []byte) (*ecdsa.PublicKey, error) { // 校验输入长度是否符合非压缩公钥要求 if len(data) != 65 { return nil, errors.New("invalid uncompressed ECDSA public key length") } // 校验是否为非压缩格式前缀 if data[0] != 0x04 { return nil, errors.New("not an uncompressed ECDSA public key") } // 拆分X、Y坐标字节 x := new(big.Int).SetBytes(data[1:33]) y := new(big.Int).SetBytes(data[33:65]) curve := elliptic.P256() // 验证坐标点是否在P256曲线上 if !curve.IsOnCurve(x, y) { return nil, errors.New("public key point is not on P256 curve") } return &ecdsa.PublicKey{ Curve: curve, X: x, Y: y, }, nil }
使用示例
如果你的输入是十六进制字符串(比如示例中的0496cf21e333678b9c5cd0f6642e93f81e4544ef199ac0144404866309a139a421c5cf948b5ec8baefebaaf2af248835bf8b3f5c8570ff300c6f693f4015a39095),可以先转成字节数组再调用:
import "encoding/hex" hexStr := "0496cf21e333678b9c5cd0f6642e93f81e4544ef199ac0144404866309a139a421c5cf948b5ec8baefebaaf2af248835bf8b3f5c8570ff300c6f693f4015a39095" data, err := hex.DecodeString(hexStr) if err != nil { // 处理十六进制解码错误 } pubKey, err := HexToPublicKey(data) if err != nil { // 处理公钥解析错误 }
关键说明
- 加入校验后,能有效拦截非法输入(比如长度不符、格式错误、伪造的曲线点)
- 错误信息明确,方便调用方快速定位问题
- 完全兼容你提供的第三方公钥格式(通过ECDH生成的非压缩公钥)
内容的提问来源于stack exchange,提问作者mogoman
相关产品推荐
相关产品推荐

