package sm2 import ( "crypto/ecdsa" "crypto/rand" "encoding/asn1" "encoding/base64" "encoding/hex" "encoding/pem" "errors" "fmt" "strings" "testing" ) const publicKeyPemFromAliKms = `-----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAELfjZP28bYfGSvbODYlXiB5bcoXE+ 2LRjjpIH3DcCCct9FuVhi9cm60nDFrbW49k2D3GJco2iWPlr0+5LV+t4AQ== -----END PUBLIC KEY----- ` const publicKeyPemFromAliKmsForSign = `-----BEGIN PUBLIC KEY----- MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAERrsLH25zLm2LIo6tivZM9afLprSX 6TCKAmQJArAO7VOtZyW4PQwfaTsUIF7IXEFG4iI8bNuTQwMykUzLu2ypEA== -----END PUBLIC KEY----- ` const hashBase64 = `Zsfw9GLu7dnR8tRr3BDk4kFnxIdc8veiKX2gK49LqOA=` const signature = `MEUCIHV5hOCgYzlO4HkrUhct1Cc8BeKmbXNP+ASje5rGOcCYAiEA2XOajXo3/IihtCEJmNpImtWw3uHIy5CX5TIxit7V0gQ=` func getPublicKey(pemContent []byte) (interface{}, error) { block, _ := pem.Decode(pemContent) if block == nil { return nil, errors.New("Failed to parse PEM block") } return ParsePKIXPublicKey(block.Bytes) } func TestSignByAliVerifyAtLocal(t *testing.T) { var rs = &ecdsaSignature{} dig, err := base64.StdEncoding.DecodeString(signature) if err != nil { t.Fatal(err) } rest, err := asn1.Unmarshal(dig, rs) if err != nil { t.Fatal(err) } if len(rest) != 0 { t.Errorf("rest len=%d", len(rest)) } fmt.Printf("r=%s, s=%s\n", hex.EncodeToString(rs.R.Bytes()), hex.EncodeToString(rs.S.Bytes())) pub, err := getPublicKey([]byte(publicKeyPemFromAliKmsForSign)) pub1 := pub.(*ecdsa.PublicKey) hashValue, _ := base64.StdEncoding.DecodeString(hashBase64) result := Verify(pub1, hashValue, rs.R, rs.S) if !result { t.Error("Verify fail") } } func TestParsePKIXPublicKey(t *testing.T) { pub, err := getPublicKey([]byte(publicKeyPemFromAliKms)) if err != nil { t.Fatal(err) } pub1 := pub.(*ecdsa.PublicKey) encrypted, err := Encrypt(rand.Reader, pub1, []byte("testfile")) if err != nil { t.Fatal(err) } fmt.Printf("encrypted=%s\n", base64.StdEncoding.EncodeToString(encrypted)) } func TestMarshalPKIXPublicKey(t *testing.T) { pub, err := getPublicKey([]byte(publicKeyPemFromAliKms)) if err != nil { t.Fatal(err) } result, err := MarshalPKIXPublicKey(pub) if err != nil { t.Fatal(err) } block := &pem.Block{Bytes: result, Type: "PUBLIC KEY"} pemContent := string(pem.EncodeToMemory(block)) if !strings.EqualFold(publicKeyPemFromAliKms, pemContent) { t.Errorf("expected=%s, result=%s", publicKeyPemFromAliKms, pemContent) } }