慕哥6287543
您正在尝试解组原始 ASN.1 消息,而不是公钥部分。您应该首先解组 ASN.1 块,然后解组 EC 数据。我的评论是错误的,Go 不支持 Brainpool 功能。因此,我从他们的 X509 包中借用了一些代码,为 Brainpool 包中的 6 条曲线构建了一个自定义解析器。游乐场:https://play.golang.org/p/i-Zd4mTugjUpackage mainimport ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" "crypto/sha256" "crypto/x509/pkix" "encoding/asn1" "encoding/pem" "errors" "fmt" "log" "math/big" "github.com/keybase/go-crypto/brainpool")const ecKey = `-----BEGIN PUBLIC KEY-----MIGbMBQGByqGSM49AgEGCSskAwMCCAEBDQOBggAEM/zOLT7nMN374k902oTRZXnG97DPzvqi8QQJaKXcq1BSrU/sNeUhOi6Y+hBcr7ZE+WZDYNoQkaMNrdhF+3x1XGx7BTBFL3U1w2ENmkIPiDa2o0Q/wpSOLo/RFabdK5Q3/yvq0hoSdXlpKozE7UTre5cUbJcUzjXvs9KDLEq54Fs=-----END PUBLIC KEY-----`func main() { block, _ := pem.Decode([]byte(ecKey)) if block == nil || block.Type != "PUBLIC KEY" { log.Fatal("failed to decode PEM") } pub, err := parseBrainpoolPKIXPublicKey(block.Bytes) if err != nil { log.Fatalf("failed to parse key: %v", err) } pubb := ecdsa.PublicKey{Curve: brainpool.P512r1(), X: pub.X, Y: pub.Y} priva, _ := ecdsa.GenerateKey(brainpool.P512r1(), rand.Reader) b, _ := pubb.Curve.ScalarMult(pubb.X, pubb.Y, priva.D.Bytes()) shared1 := sha256.Sum256(b.Bytes()) fmt.Printf("\nShared key %x\n", shared1)}type publicKeyInfo struct { Raw asn1.RawContent Algorithm pkix.AlgorithmIdentifier PublicKey asn1.BitString}type pkcs1PublicKey struct { N *big.Int E int}var ( oidNamedCurveBrainpoolP256r1 = asn1.ObjectIdentifier{1, 3, 36, 3, 3, 2, 8, 1, 1, 7} oidNamedCurveBrainpoolP256t1 = asn1.ObjectIdentifier{1, 3, 36, 3, 3, 2, 8, 1, 1, 8} oidNamedCurveBrainpoolP384r1 = asn1.ObjectIdentifier{1, 3, 36, 3, 3, 2, 8, 1, 1, 11} oidNamedCurveBrainpoolP384t1 = asn1.ObjectIdentifier{1, 3, 36, 3, 3, 2, 8, 1, 1, 12} oidNamedCurveBrainpoolP512r1 = asn1.ObjectIdentifier{1, 3, 36, 3, 3, 2, 8, 1, 1, 13} oidNamedCurveBrainpoolP512t1 = asn1.ObjectIdentifier{1, 3, 36, 3, 3, 2, 8, 1, 1, 14})func parseBrainpoolPKIXPublicKey(derBytes []byte) (pub *ecdsa.PublicKey, err error) { var pki publicKeyInfo if rest, err := asn1.Unmarshal(derBytes, &pki); err != nil { if _, err := asn1.Unmarshal(derBytes, &pkcs1PublicKey{}); err == nil { return nil, errors.New("failed to parse public key") } return nil, err } else if len(rest) != 0 { return nil, errors.New("trailing data after ASN.1 of public-key") } if !pki.Algorithm.Algorithm.Equal(asn1.ObjectIdentifier{1, 2, 840, 10045, 2, 1}) { return nil, errors.New("not an ECDSA public key") } return parseBrainpoolPublicKey(&pki)}func parseBrainpoolPublicKey(keyData *publicKeyInfo) (*ecdsa.PublicKey, error) { asn1Data := keyData.PublicKey.RightAlign() paramsData := keyData.Algorithm.Parameters.FullBytes namedCurveOID := new(asn1.ObjectIdentifier) rest, err := asn1.Unmarshal(paramsData, namedCurveOID) if err != nil { return nil, errors.New("failed to parse ECDSA parameters as named curve") } if len(rest) != 0 { return nil, errors.New("trailing data after ECDSA parameters") } namedCurve := namedCurveFromOID(*namedCurveOID) if namedCurve == nil { return nil, errors.New("unsupported elliptic curve") } x, y := elliptic.Unmarshal(namedCurve, asn1Data) if x == nil { return nil, errors.New("failed to unmarshal elliptic curve point") } pub := &ecdsa.PublicKey{ Curve: namedCurve, X: x, Y: y, } return pub, nil}func namedCurveFromOID(oid asn1.ObjectIdentifier) elliptic.Curve { switch { case oid.Equal(oidNamedCurveBrainpoolP256r1): return brainpool.P256r1() case oid.Equal(oidNamedCurveBrainpoolP256t1): return brainpool.P256t1() case oid.Equal(oidNamedCurveBrainpoolP384r1): return brainpool.P384r1() case oid.Equal(oidNamedCurveBrainpoolP384t1): return brainpool.P384t1() case oid.Equal(oidNamedCurveBrainpoolP512r1): return brainpool.P512r1() case oid.Equal(oidNamedCurveBrainpoolP512t1): return brainpool.P512t1() } return nil}