我尝试使用PHP创建可为某些文档创建ECDSA签名的应用程序,并使用Golang应用程序验证该签名。
我使用由openssl工具生成的私钥。这是prime256v1曲线密钥。用以下命令创建:
openssl ecparam -name prime256v1 -genkey -noout -out prime256v1-key.pem
在PHP中,我使用openssl_sign函数创建签名。
我所有使用Golang验证签名的尝试都失败了。在Golang中使用crypto / ecdsa,crypto / elliptic软件包。
有我的代码。
的PHP
高朗
package main import ( "crypto/ecdsa" "crypto/elliptic" "crypto/md5" "encoding/hex" "fmt" "io" "io/ioutil" "math/big" "crypto/x509" "encoding/pem" ) func main() { stringtosign := "my test string to sign" // This is outpur of PHP app. Signature generated by PHP openssl_sign signature := "18d5c1d044a4a752ad91bc06499c72a590b2842b3d3b4c4b1086bfd0eea3e7eb5c06b77e15542e5ba944f3a1a613c24eabaefa4e2b2251bd8c9355bba4d14640" // NOTE . Error verificaion is skipped here // Privcate key was geerated with openssl tool with the command // openssl ecparam -name prime256v1 -genkey -noout -out prime256v1-key.pem prikeybytes, _ := ioutil.ReadFile("prime256v1-key.pem") p, _ := pem.Decode(prikeybytes) prikey, _ := x509.ParseECPrivateKey(p.Bytes) signatureBytes, _ := hex.DecodeString(signature) // make MD5 hash h := md5.New() io.WriteString(h, stringtosign) data := h.Sum(nil) // build key and verify data r := big.Int{} s := big.Int{} // make signature numbers sigLen := len(signatureBytes) r.SetBytes(signatureBytes[:(sigLen / 2)]) s.SetBytes(signatureBytes[(sigLen / 2):]) curve := elliptic.P256() // make public key from private key x := big.Int{} y := big.Int{} x.SetBytes(prikey.PublicKey.X.Bytes()) y.SetBytes(prikey.PublicKey.Y.Bytes()) rawPubKey := ecdsa.PublicKey{Curve: curve, X: &x, Y: &y} v := ecdsa.Verify(&rawPubKey, data, &r, &s) if v { fmt.Println("Success verify!") return } fmt.Println(fmt.Sprintf("Signatire doed not match")) }我做错了什么?谁能给我展示一个工作示例,其中Golang验证用PHP创建的签名吗?
我尝试在openssl_sign中使用不同版本,而不是OPENSSL_ALGO_SHA256。尝试过OPENSSL_ALGO_SHA1,OPENSSL_ALGO_SHA512