<?php declare(strict_types=1); ini_set('display_errors', 'On'); error_reporting(-1); $privateKeyFile = __DIR__ . '/rsa_private_key.pem'; // 私钥文件路径 $privateKeyContents = file_get_contents($privateKeyFile); // 获取私钥的内容(即字符串) $privateKeyResource = openssl_pkey_get_private($privateKeyContents); $privateKeyResource === false && exit('openssl_pkey_get_private() is false.'); // 签名参数 $params = ['name' => '张三', 'gender' => '男', 'birth' => 2003]; // 按照参数名ASCII字典序排序(即按照a~z升序) ksort($params); // 转成“key1=value1&key2=value2&key3=value3”格式的字符串 $data = urldecode(http_build_query($params)); $signature = ''; // 生成签名,这里openssl_sign()函数缺省签名算法参数(第四个参数),即使用缺省值OPENSSL_ALGO_SHA1 openssl_sign($data, $signature, $privateKeyResource) || exit('openssl_sign() is false.'); $signature = base64_encode($signature); echo "$data ===> $signature"; // birth=2003&gender=男&name=张三 ===> cv7MwgoDnX47VZDu2w8eREr/hCisbKeOmPIjjfdvPAdWTKgEpfXXLi1RlYI/hNVOsytVwFp3kEm+8DAAtQzNIKJ7UXjHi/kCFCLhTkQQjOg0Ci8xer3t4OLtOZgx0/UwPAAzrR3UDQKKZl12VVtQSQraMlTik8ILuksB0xvDoOx5dkVTWJKDmM4E7zrYGP15Z9F6vrK9gSi9aIri75ZOnCXHi27qCF0LEdhkrj5nCHdWw9/sdAWGqxYcAtjNpgDuI/ek7uGnaP6sIpK0pGc3J85Kge+KyDXPb6fRRFyNAHh4tt3BKppAtGl2OSpJDtjp9LiFIPXV3mrFPYnahFUyiA==
package main import ( "crypto" "crypto/rsa" "crypto/sha1" "crypto/x509" "encoding/base64" "encoding/pem" "fmt" "os" "path/filepath" ) func main() { currentPath, err := filepath.Abs(".") if err != nil { panic("获取当前路径出错:" + err.Error()) } // 构造公钥文件的硬盘路径 publicKeyFile := currentPath + "/rsa_public_key.pem" // 打开公钥文件 var file *os.File file, err = os.Open(publicKeyFile) if err != nil { panic("打开公钥文件出错:" + err.Error()) } // 关闭公钥文件 defer func(file *os.File) { err = file.Close() if err != nil { panic("关闭公钥文件出错:" + err.Error()) } }(file) // 读取公钥文件 contents, _ := file.Stat() buffers := make([]byte, contents.Size()) _, err = file.Read(buffers) if err != nil { panic("读取公钥文件出错:" + err.Error()) } // 解析公钥文件 var publicKeyAny any pemDecode, _ := pem.Decode(buffers) // pem解码 publicKeyAny, err = x509.ParsePKIXPublicKey(pemDecode.Bytes) // x509解码 if err != nil { panic("解析公钥文件出错:" + err.Error()) } // 断言 publicKey, ok := publicKeyAny.(*rsa.PublicKey) if !ok { panic("不是合法的公钥文件") } // 签名参数 params := "birth=2003&gender=男&name=张三" // 签名字符串 signature := "cv7MwgoDnX47VZDu2w8eREr/hCisbKeOmPIjjfdvPAdWTKgEpfXXLi1RlYI/hNVOsytVwFp3kEm+8DAAtQzNIKJ7UXjHi/kCFCLhTkQQjOg0Ci8xer3t4OLtOZgx0/UwPAAzrR3UDQKKZl12VVtQSQraMlTik8ILuksB0xvDoOx5dkVTWJKDmM4E7zrYGP15Z9F6vrK9gSi9aIri75ZOnCXHi27qCF0LEdhkrj5nCHdWw9/sdAWGqxYcAtjNpgDuI/ek7uGnaP6sIpK0pGc3J85Kge+KyDXPb6fRRFyNAHh4tt3BKppAtGl2OSpJDtjp9LiFIPXV3mrFPYnahFUyiA==" // 签名字符串是base64编码,需要先解码 var sig []byte sig, err = base64.StdEncoding.DecodeString(signature) if err != nil { panic("base64解码出错:" + err.Error()) } hash := sha1.New() // 重要说明:生成签名时使用SHA1算法,这里要用sha1.New() _, err = hash.Write([]byte(params)) if err != nil { panic("写入哈希对象出错:" + err.Error()) } hashSum := hash.Sum(nil) // 使用公钥验证签名 err = rsa.VerifyPKCS1v15(publicKey, crypto.SHA1, hashSum, sig) // 重要说明:生成签名时使用SHA1算法,这里要用crypto.SHA1 if err != nil { fmt.Println("签名错误:", err.Error()) } else { fmt.Println("签名正确") } }
Copyright © 2024 码农人生. All Rights Reserved