签名方式
所有的POST
请求都需要进行 签名 (opens new window)。
# 说明
- 加签内容为:
appid
+X-Timestamp
+body
,使用商户私钥
进行加签
。 Authorization
,Sign
,X-Timestamp
,content-Type
这几个参数必填。- 签名的时间戳(毫秒级)通过
X-Timestamp
参数传输。 body
里如果有Emoji
、小语种
需要转义处理,不然会验签不通过。
# 示例
package com.pyvio.developer.sdk.aop;
import org.apache.commons.codec.binary.Base64;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
public class SignTest {
/**
* 参数签名(${appId}${timestamp}${requestBody})
* @param content
* @param privateKey
* @return
* @throws Exception
*/
public static String sign(String content,String privateKey) throws Exception {
Signature signature = Signature.getInstance("SHA256WithRSA");
PrivateKey prk = getPrivateKeyFromPKCS8("RSA",privateKey);
signature.initSign(prk);
byte[] bytes = content.getBytes("UTF-8");
signature.update(bytes);
byte[] signed = signature.sign();
return Base64.encodeBase64String(signed);
}
public static boolean signCheck(String content,String sign, String publicKey) {
try {
PublicKey pubKey = getPublicKeyFromX509("RSA", publicKey);
java.security.Signature signature = java.security.Signature.getInstance("SHA256WithRSA");
signature.initVerify(pubKey);
signature.update(content.getBytes("UTF-8"));
return signature.verify(Base64.decodeBase64(sign.getBytes()));
} catch (Exception e) {
return false;
}
}
private static PrivateKey getPrivateKeyFromPKCS8(String algorithm, String privateKey) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
byte[] encodedKey = privateKey.getBytes();
encodedKey = Base64.decodeBase64(encodedKey);
return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
}
private static PublicKey getPublicKeyFromX509(String algorithm, String publicKey) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
byte[] encodedKey = publicKey.getBytes();
encodedKey = Base64.decodeBase64(encodedKey);
return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
}
public static void main(String[] args) throws Exception {
//partner app id
String appId = "1569641270953589504";
//request time
Long timestamp = 1666332361000L;
//partner rsa private key
String privateKey = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBALxGyg3/boLT2I8dQnC3Njc2XIDJgZM/G4wqsDDUVoy/PQ2THA39sKHiLsTg71zVbQZ4+UYWm1aTlms7KuBuOmvmdIzKuI04NbSuDeAbAtnraizhELSOpVQFNom2tIGHw4/46VuF3bE0rgFjKGqrRI9xOVEcDGZlP4h9JatQEgytAgMBAAECgYADZ1dX9Awy+A+NlAFm4BQrcXFy1xt7GIGUHaSUCe3N7sxY45uB+F+vyVh6aJm74QlCaJvmQv62Lg5t1HOQ2pcHD6/r7G0lykjYJ3JEAmF3KKm/FgPqX9MGqZCBNHp3oQaHMf8WwRfjxr/EBT1QfdItCGjiENJ4bjSJo9qzEPtjSQJBAMx/r6clsTUdpeskw60UMJG17Af5Fc/SNCsq8hdmCqva0QtT1l/vprmwEH1hKXlA9au9cIESp0ceABH86jE9Vu8CQQDrsTt/S6iiWAiJKA8eYWSEcPyQXoB+tveg4ZoKUwG+fT5t9tXOuPZGmC7CWsAATfO88/ySGqNyIlFgSDvTM3YjAkB+c9JdLCyI6L1pSwGIq/xgjbrXL0oyiQvjSZoLp/ifTh6Hv57HEfzpw5pevU8VAHspaGoCFlPD4SQv+1GhgwmXAkAd6grBJ1sp7751mg4BLx9Q5/5GXJg2fQaE9t1UPiDUipTn5BJTAIrRfvNAW8BOyZYL/3OpH5RrIgvuCnz9W2S9AkB19MQtKSc3Ba36Jo3C0kvTdeSDBR4o+ah+bzhwg/Hj8EKYp4IoyW8mx32WXtSLGp8OjupPlZ65PUkzy838Eo8v";
//partner rsa public key
String publicKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC8RsoN/26C09iPHUJwtzY3NlyAyYGTPxuMKrAw1FaMvz0NkxwN/bCh4i7E4O9c1W0GePlGFptWk5ZrOyrgbjpr5nSMyriNODW0rg3gGwLZ62os4RC0jqVUBTaJtrSBh8OP+Olbhd2xNK4BYyhqq0SPcTlRHAxmZT+IfSWrUBIMrQIDAQAB";
// post request json body,read from request stream
String requestBody = "{\"grant_type\":\"client_credentials\",\"app_id\":\"1569641270953589505\",\"app_secret\":\"bc2ead7739f447c49032b4aef7818c47\"}";
//generate rule
String signContent = appId + timestamp + requestBody;
String sign = sign(signContent,privateKey);
System.out.println(sign);
System.out.println(signCheck(signContent,sign,publicKey));
}
}
function sign($content, $privateKey)
{
$signature = "";
$privateKey = openssl_pkey_get_private($privateKey);
openssl_sign($content, $signature, $privateKey, OPENSSL_ALGO_SHA256);
openssl_free_key($privateKey);
return base64_encode($signature);
}
function signCheck($content, $sign, $publicKey)
{
$publicKey = openssl_pkey_get_public($publicKey);
$result = openssl_verify($content, base64_decode($sign), $publicKey, OPENSSL_ALGO_SHA256);
openssl_free_key($publicKey);
return $result === 1;
}
// partner rsa private key
$privateKey = "-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDmvlJQoH9k7iIY
/nv7/js9NVPqsIJL/lqmILx/wYL4Kq0d4i49L10xySR4IknQ17W3PkmAklIs+jwZ
KXejnerOJKwd06ss9xCnoUwxMmS7/R7p0XTyqFksI2DxaDn11IJ1tayn/qdRx58b
g6k3+VvJXfOAfYC99ZqDyg0h7b54Hu2BtbjLnQCWkJamUN3foygokZKrNp9ONEVm
kc7/bRR2lxFDFpyaxUWTElZgv1T1w7QpmiX3mtawcU5ydhMiArF4BfRfsk+IoAeq
tKfvWf0vvMAtusf2m8KtSA9sQt27zXgObU+KzKOTUXFz8MgYwJxs41nIDfFyCvMg
bdKrW/XNAgMBAAECggEBAOSWtXt0lOBLXXI/YlqxcMRheUHuHRbl463ijntOHM53
kMsjEEXDD2NL7hopddE0cawYQ77gthIi0LjosMJhpoUUJYLi+Bhypog6rf2q+8qU
pzRiMaZXiwfEAL0HUSwtnBS6p1JCYEYPKZubYl+2Y+zoa1vmeU027B0VZM8w9NmP
gIXJHr5LquvBpYx8q11bGgyDnxYHcHxBJnc6Nt31RfxUZBlMKCpfqiK2lpoCaN8a
Kb325DcQg0ut70/eajAnriNdi3CcSVsIxqMCMabJeWEf+57i2+R7lz+WKjjM5YP9
VYDMoDAlEfyBG1Utf/J9U2va7CBfbkDDKK2su5EtYAECgYEA9qJZW6FYx8qmuk9e
dJFl2mGu4QQUOiGkEBtuoUj45ao8vaQ4AeXpcxibkWYt31mDb1UHt7H5HMtwlaZL
q7PBmksit3aJHcfibZ0FKNaTJqh3vE59jePziJj1cDz7TCoBuWA3fKocdDutAavw
66pSeJrWq8JjrM+6H1QKk6r8bc0CgYEA74F9riclXO25/ssLSNGti0IB4XymeOPt
NYpZXfNpiG+wyo8NmWg6F/fwhT/d2AmoW2pZRavFx5V7s1JKzLFeZ9ljQ6sibaNZ
UgoF7LdtXdGR/NaVFf0xhASduJ4Dvl/Yrg9orkWMp2ih5OAvwZ5yeD5c2WHbwBvS
aqaYozCVqAECgYEAwd2NtfwW6D1AX3Th/2kHEej06QUmzScCanLVvEu68fSl+D+s
krlhjspKBrm11znqmcnR3jA0a9Dyd3+XPal3xkvHR0UStOkY8CacFqTMWHfWXpuo
D6+eD8KEMyyMMCtY3ZlnJEQnR6pc7NJ19xkT6J91nN+ZMA6888FA6yBdegUCgYBV
eMS9TcMLstrZjuRsDEf+loPNUIqoQc75eHIEEUXsJs/UudCEmqmAvD7djrlAy9GF
LiLFtlNSson+qLOA8RtbvDysfXo/3jeWC3Wp0Jv7CzsqG/oAaucs0ejnZZy4Z8QP
+ffFmZRkefask0T3t+/p8Xd5LG8b09H3tZRrSH9gAQKBgQCSFc93PF11GdubIn92
3/J5U9l+UCwmqCdjLWmPzwQxXFE7RYb9k7RYMXkTirfSEI6YssD4PFNbVFMfxgZD
DotZ28xnWFXe0Ws9AqeErAXRNVXeEmDN5Ii/fa40SFUyeD9URg1f1IsunfekX2J2
AK3yEtTe6TCUJpgTJVEGvjwMeQ==
-----END PRIVATE KEY-----";
// partner rsa public key
$publicKey = "-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5r5SUKB/ZO4iGP57+/47
PTVT6rCCS/5apiC8f8GC+CqtHeIuPS9dMckkeCJJ0Ne1tz5JgJJSLPo8GSl3o53q
ziSsHdOrLPcQp6FMMTJku/0e6dF08qhZLCNg8Wg59dSCdbWsp/6nUcefG4OpN/lb
yV3zgH2AvfWag8oNIe2+eB7tgbW4y50AlpCWplDd36MoKJGSqzafTjRFZpHO/20U
dpcRQxacmsVFkxJWYL9U9cO0KZol95rWsHFOcnYTIgKxeAX0X7JPiKAHqrSn71n9
L7zALbrH9pvCrUgPbELdu814Dm1Pisyjk1Fxc/DIGMCcbONZyA3xcgrzIG3Sq1v1
zQIDAQAB
-----END PUBLIC KEY-----";
// post request json body, read from request stream
$requestBody = "{\"grant_type\":\"client_credentials\",\"app_id\":\"1674044218623168131\",\"app_secret\":\"4bc77e23e6fd438fbc6d887ba8574726\"}";
// partner app id
$appId = "1674044218623168131";
// request time
$timestamp = 1688624702643;
// generate rule
$signContent = $appId . $timestamp . $requestBody;
$sign = sign($signContent, $privateKey);
var_dump($signContent);
$check = signCheck($signContent, $sign, $publicKey);
var_dump($check);
// Make sure to add code blocks to your code group