3. 计算签名值
绝大多数编程语言提供的签名函数支持对签名数据进行签名。强烈建议商户调用该类函数,使用商户私钥对待签名串进行SHA256 with RSA签名,并对签名结果进行Base64编码得到签名值。
1$ echo -n -e \
2 'GET\n/v3/refund/domestic/refunds/123123123123\n1554208460\n593BEC0C930BF1AFEB40B4A08C8FB242\n\n' \
3 | openssl dgst -sha256 -sign apiclient_test_key.pem \
4 | openssl base64 -A

using System; using System.Net.Http; using System.Security.Cryptography; using System.Text; class Program { static async Task Main(string[] args) { // 定义请求URL string requestUrl = "https://api.mch.weixin.qq.com/v3/certificates"; // 商户相关参数 string mchId = "1900007291"; string nonceStr = "593BEC0C930BF1AFEB40B4A08C8FB242"; string timestamp = "1554208460"; string serialNo = "408B07E79B8269FEC3D5D3E6AB8ED163A6A380DB"; // 这里需要替换为实际的商户私钥(PEM格式) string privateKey = @"-----BEGIN PRIVATE KEY----- MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC... -----END PRIVATE KEY-----"; // 生成签名 string signature = GenerateSignature("GET", requestUrl, timestamp, nonceStr, "", privateKey); // 构造Authorization头 string authHeader = $"WECHATPAY2-SHA256-RSA2048 mchid=\"{mchId}\",nonce_str=\"{nonceStr}\",signature=\"{signature}\",timestamp=\"{timestamp}\",serial_no=\"{serialNo}\""; // 发送请求 await SendRequest(requestUrl, authHeader); } static string GenerateSignature(string httpMethod, string url, string timestamp, string nonceStr, string body, string privateKey) { // 提取URL路径 Uri uri = new Uri(url); string urlPath = uri.PathAndQuery; // 构造待签名串 string message = $"{httpMethod}\n" + $"{urlPath}\n" + $"{timestamp}\n" + $"{nonceStr}\n" + $"{body}\n"; // 将私钥转换为RSA对象 using (RSA rsa = RSA.Create()) { // 导入私钥(移除PEM头尾和换行) string keyContent = privateKey .Replace("-----BEGIN PRIVATE KEY-----", "") .Replace("-----END PRIVATE KEY-----", "") .Replace("\n", "") .Replace("\r", ""); byte[] keyBytes = Convert.FromBase64String(keyContent); rsa.ImportPkcs8PrivateKey(keyBytes, out _); // SHA256withRSA签名 byte[] messageBytes = Encoding.UTF8.GetBytes(message); byte[] signatureBytes = rsa.SignData(messageBytes, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1); // Base64编码 return Convert.ToBase64String(signatureBytes); } } static async Task SendRequest(string url, string authHeader) { using (HttpClient client = new HttpClient()) { // 设置Authorization头 client.DefaultRequestHeaders.Add("Authorization", authHeader); try { // 发送GET请求 HttpResponseMessage response = await client.GetAsync(url); // 打印状态码和响应体 Console.WriteLine($"HTTP Status Code: {(int)response.StatusCode}"); string responseBody = await response.Content.ReadAsStringAsync(); Console.WriteLine("Response Body:"); Console.WriteLine(responseBody); } catch (Exception ex) { Console.WriteLine($"Error: {ex.Message}"); } } } }