更新日期:2026-06-25QuickSDK数据回调RSA签名方案文档
聚合sdk默认生成2048字节的密钥对,提供的参数均为公钥,私钥由sdk保存。
一、操作流程
在创建产品的时候,选择回调协议
创建产品之后,可以到控制台的“游戏参数”查看参数,或者再次选择更换回调协议。这里只展示publicKey和publicRsaKey
二、密钥说明
两对独立的 RSA 密钥,职责不同:
| 密钥对 | 变量名 | 用途 | 算法 |
|---|---|---|---|
|
第一对
|
$privateKey / $publicKey
|
数据 加密 / 解密
|
RSA PKCS#1 v1.5(
OPENSSL_PKCS1_PADDING)
|
|
第二对
|
$privateRsaKey / $publicRsaKey
|
数据 签名 / 验签
|
RSA + SHA256(
OPENSSL_ALGO_SHA256)
|
三、回调数据结构示例
原则上数据结构与之前的方案完全保持一致,只是现在的方案获取到的数据为JSON格式,参考数据如下。
| 字段 | 示例值 | 说明 |
|---|---|---|
is_test
|
0
|
是否测试订单(0=正式,1=测试)
|
channel
|
3366
|
渠道 ID
|
channel_name
|
channelName
|
渠道名称
|
channel_uid
|
112355669
|
渠道用户 ID
|
channel_order
|
0020260508195341811555
|
渠道订单号
|
game_order
|
QK2026050869042052718565097869312
|
游戏订单号
|
order_no
|
336620260508195338968965178
|
平台订单号
|
pay_time
|
2026-05-08 19:53:52
|
支付时间
|
amount
|
66.00
|
支付金额(验证金额是否一致)
|
status
|
0
|
订单状态
|
extras_params
|
1622726932175773696_13707_1782181790395_1301_好好学习
|
扩展参数
|
原始数据示例如下:
{"is_test":0,"channel":3366,"channel_name":"channelName","channel_uid":112355669,"channel_order":"0020260508195341811555","game_order":"QK2026050869042052718565097869312","order_no":"336620260508195338968965178","pay_time":"2026-05-08 19:53:52","amount":66,"status":0,"extras_params":"1622726932175773696_13707_1782181790395_1301_好好学习"}
四、核心流程
$data 转为 JSON 字符串 $json_data
openssl_private_encrypt(),使用 $privateKey
QuickBase64Code::safe_base64_encode() 得到 $crypted_result
$json_data(不分块)调用 openssl_sign()
$privateRsaKey,算法为 OPENSSL_ALGO_SHA256
QuickBase64Code::safe_base64_encode() 得到 $sign_result
QuickBase64Code::safe_base64_decode($crypted_result)
openssl_public_decrypt(),使用 $publicKey
$decrypted_result(应与原始 JSON 一致)
$sign_result)
$decrypted_result 调用 openssl_verify(),使用 $publicRsaKey
SUCCESS,否则输出 FAILURE
QuickBase64Code 实现 URL 安全 Base64(类似 RFC 4648):
| 操作 | 规则 |
|---|---|
|
编码
|
标准 Base64 后,
+ → -,/ → _,并去掉末尾 =
|
|
解码
|
- → +,_ → /,补齐 = 至长度为 4 的倍数,再 base64_decode
|
适用于在 URL 或 API 参数中传递加密数据和签名。
class QuickBase64Code{
public static function safe_base64_encode($data)
{
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
public static function safe_base64_decode($data)
{
$data = strtr($data, '-_', '+/');
$padding = strlen($data) % 4;
if ($padding) {
$data .= str_repeat('=', 4 - $padding);
}
return base64_decode($data);
}
}
五、发货数据
最终发货请求数据为data sign requestId 三个字段,请求方式为POST
研发再收到数据之后,解密并验证签名成功之后,返回7个大写的字符SUCCESS即为发货成功。
data请使用publicKey进行解密,成功解密之后就可以得到如上述(第三)示例的Json数据。
sign请使用publicRsaKey进行验证,验证主体为上一步解密得到的Json串。
requestId为uuid可作为日志标记参考
请求示例:
data=dpYGrd4dN2Q1OMvWStxivKwqFdxFaoOjqFOHArS0fqQbTuPYAHKiA3EuImIgxEW0XiADE5OhjRla7ELuPjNYYiZ02ZEbYxZvFUEvA-NNvaizwSBXVbbPjKDnnyfd3RyyZq99GahIKBEtsJzobTJMpfzKrsOra8t0wPZ8lO8g00WWNtO29NQoISHI6AqFqNWXxbWdn90Ag1oniLKjmO9GmoSUtSCoz2YxItnMBlamSa9hRVr0icjz4IYL1hsk9cyfoWSDBE7iP9ap0mQY5BxqEKO70a5clxy-Lek48kQKJVuTWrqvJEJ46HCTIow65Sk-Cjj4RwVRIG0ZXUjClI5rpUu_tit1uRakyBoUhUmhQp9EiG7K_E7ZAN0PEg1sY0_mdYbREJyDy1xKMSezspnIchFa-xj-pJ45NDcC-Grk0LjA1ua82o0PlQSs-fAl7gfgoM2DzK57lW6rtJQ49KY8FU16VjXLk7GvuhCjHChZET-dcV9YYCe9Yoz678-7dUfmqGI4gGi7ky-irvY0kTek0thh3sJmnlKj0hp19bgazhN4kPe-ahs3nRv5SwdYrfQWcSWOWmzXWGkIoXqEk6s6VMA2W5QPh7k1Re9C72BS1OCAWwYiwffFK0dLBRJAUT4llXXcjLX7s0dJwdDTZuW3j-Zvsjs0i_EQqUHiPWQAiYo&sign=kNZq-3ej_8kF_idY-AlEmZD0aUohzMw_UReyHzWp2OPjnTWOilRdbRBeyaYXJ7TawWbLVYJ925MPBqbk7KJDue41-fpZRp3bp6fA9Fy87Nj2u3S9ZskoIAJ-wQZ2njJp-ZII6k5QqvOmRsfEHBoZYYrEtzN1ZlBCoduxUBUMR16e6JqHjNMY9dejAYZ6bI8q87EJfiRAoPHwS_rB2rok_I5yY1TvQHBcwLjsS9VM0HHdm3O5b4xIyKf2e2D-_fQcb1D2DIISkzfDmEumAXn6pTsXU9hoePsXGLGh8BPdnhvrVhw5qLwTeA1J8fNSJoBLBVPZpJk572YPdrykDm6kwA&requestId=70dd3c1b-dc79-4921-8176-667dde689eb8
六、完整伪代码
$data['is_test'] = 0;
$data['channel'] = 3366;
$data['channel_name'] = 'channelName';
$data['channel_uid'] = 112355669;
$data['channel_order'] = '0020260508195341811555';
$data['game_order'] = 'QK2026050869042052718565097869312';
$data['order_no'] = '336620260508195338968965178';
$data['pay_time'] = '2026-05-08 19:53:52';
$data['amount'] = 66.00;
$data['status'] = 0;
$data['extras_params'] = '1622726932175773696_13707_1782181790395_1301_好好学习';
echo PHP_EOL;echo PHP_EOL;
$json_data = json_encode($data, JSON_UNESCAPED_UNICODE | JSON_BIGINT_AS_STRING);
echo "原始数据:";echo $json_data;
echo PHP_EOL;echo PHP_EOL;
//===================================================================================================================//
$publicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw3PmIRXevYkI0RalTUU8oi+keLd06P9qPJnVsh1tZkE0Sa5lcpAqOTGSY8dy2Ds8unWZ4sEgaxwo8CaTwDcRTHz3T/FPIQfQdserPXv5nH5mLa1spOXvcvjVvRFn1Cu5I2sIFHeeSG2nGxrZtkNxF/WAAvIXJLnoqrgg20xN8HK/XLA2/oOJqWKQmad1D+uKjEQFRnQkZf9egwzDIlcOvA+o+RlF3ehCfqsXgQOoV30bTcsRW1ueaGBD24sXx50ZxubIIt344/zdFVcFg64vJCd7p4El2VWtEmB9srsVODue95DIJIx8od/0h/QBC1KNdCOZhDPkji4yhV0qihsFhQIDAQAB";
$privateKey = "MIIEpAIBAAKCAQEAw3PmIRXevYkI0RalTUU8oi+keLd06P9qPJnVsh1tZkE0Sa5lcpAqOTGSY8dy2Ds8unWZ4sEgaxwo8CaTwDcRTHz3T/FPIQfQdserPXv5nH5mLa1spOXvcvjVvRFn1Cu5I2sIFHeeSG2nGxrZtkNxF/WAAvIXJLnoqrgg20xN8HK/XLA2/oOJqWKQmad1D+uKjEQFRnQkZf9egwzDIlcOvA+o+RlF3ehCfqsXgQOoV30bTcsRW1ueaGBD24sXx50ZxubIIt344/zdFVcFg64vJCd7p4El2VWtEmB9srsVODue95DIJIx8od/0h/QBC1KNdCOZhDPkji4yhV0qihsFhQIDAQABAoIBAGUnkIzDAtpZF6UO8VJCaRUPTzHi0LDdr5/Zhg1+yWXIjUUs6vgVwKSFEVxulvNuBQoDXzdJ+Hs2wcE4VfN/DIbnjh9jpi5UGwG+aNOTXCYwDLXLMZVOI1T/j68gWPon/tNjy3S8S8D0by3KAa8gzGE3/56GqI+rX80rKmYU4al08BJREGYCtwqK2zSTXKfTO3+iG5cc7OBz+HQZFcNCZs5lqRNZZlbHiYIDqkHQZ9x+OgNqGVRbfGS/dlWjtW9VCaHU4O0f+zAEfprSDBOunyrx50VTApkhOy4GtXgT50uKFgoFEtWkmtxwF2ZDXNYK+bukcKmh72rkKTye8eUZK+kCgYEA/8S2zbmjOG++wVouWoTZxleqG09wnlNYkAuST/QWIMb5WS0XkWEuIzDVpF04fBtvUUBk7boqSBHgbwiUuy3UAlf0WXaK3OfkKCybINVIBd7nK1G5NjR6/Xdfk+qLHntbEUQ7gVnqPkNQSzEWbF287Xci7ef9FhP7PDt0vfhfDn8CgYEAw6E0N4HOqbvtdgoXkGm1tKp7m8rm0AtPFM9Z4/wXSAJthVUB43ZT3XJqcAi87ONiQiM50GBDEYg1gmVTS4FMJ/igccSD9IK/lGoMxEn3GWTDESrZGZexRwQoZBuX3ngIUUnicM+uB3mqPtMfrKs7JVW7J4587lorkH7kCucesfsCgYEAwngpnkZ1yiV83rrY385/XwWsu1Mth9RLVErYFp66bHWdhaZ5cvp3AB7TckPG/OZHP3o8w1x3ZZDiGsple+SefKGvko5Fiy1uFvXDhbVlK8GN9ywOLR6+HRa0v1zoJmcYmQpOTE23g1vfIyzRpdeoHM4m6sknb7AFqIh0fTTp4bUCgYAZah3ggCqa/mERDqqVBkam2+cHDEsECBQT/gQNjDhyEG6t/acrJ7opcK3HNDtnAvtG4FCoc3kDFBDvib5Sds+v+arOXNtPrpS48TYLYhiJ4f89gbWGj6BmO3IL31HRgwKBnPmf8jsHmZS2aLMauXwLk6Gmt+ofBPPX58Q0bmYcdQKBgQDjcUPtn3K7tNlcIhEihvqtqQ8fh7ZKQqV92jkvf9RE45hCfg8LbSeXZ7mSU4Jv+15Z8/oFauFlXJk+sN8kHOrANzPevqhmtxZUKjhfLs00ZGhdnwWZ69WL2HthXgIkJmY3brOQmiLL011YzNKj0g+c/w2ZM9v1VxeKfGu6iuvsrQ==";
$publicRsaKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxjM2fgv4/Od+dxGjbm0iBDDnc9l0G0zMadsePVy4XzHKNRHBuOJeIG/GjB4riOc3BiWZiw8HA6gHjKL/Gs98y2zo7Y/UuWQYNkg2j9uAh4hosodtsv1Hmyo+zjcqdwAJlJyi3byrV53gNj//CwpNw0X1/v51l8Zn18tKPdXATelBvk8QHWZ40Md/+/62M7pwc40IH6Kd6hiOesOrPzO9gLzatDhekMHKODJ1vkDBZOfgzP3doqHvXZ0cw3cf/SI6ocTVnF62Tz6ybZ3hDNgeugYKZBURiDE6AvOkAzMqC0ujYVIaZ5J7X/IKT20G1yY4vMzfIrJQA6Z/6qxF1fBVEQIDAQAB";
$privateRsaKey = "MIIEowIBAAKCAQEAxjM2fgv4/Od+dxGjbm0iBDDnc9l0G0zMadsePVy4XzHKNRHBuOJeIG/GjB4riOc3BiWZiw8HA6gHjKL/Gs98y2zo7Y/UuWQYNkg2j9uAh4hosodtsv1Hmyo+zjcqdwAJlJyi3byrV53gNj//CwpNw0X1/v51l8Zn18tKPdXATelBvk8QHWZ40Md/+/62M7pwc40IH6Kd6hiOesOrPzO9gLzatDhekMHKODJ1vkDBZOfgzP3doqHvXZ0cw3cf/SI6ocTVnF62Tz6ybZ3hDNgeugYKZBURiDE6AvOkAzMqC0ujYVIaZ5J7X/IKT20G1yY4vMzfIrJQA6Z/6qxF1fBVEQIDAQABAoIBAQCLVtHGh7BCTJUyLGpTZdH2VFNDtOrVjoZfHTcDOL493okkChnBWxOFhk91jnhYxQSAA8sQYj4yKd002Bq0xI4djbGr4eRRebcz4kzJki2oGxRP/rn2je3bfjWtUEdAZfxWSFCPxuZGsK1CNnedUV8eG384B7iwPUIgCcFl+3I40rgSBpA1F+bpaJ59YXEtIl6tEkP+dL3J6q9znwNn7kbsgqInK+Jd4Ddm5WrGNhxO1/sDcFvFLzqI8qDISQPsNx+F0M22ThTwttdfaDQk0dOr3AOwKRA1y9xsF+8MyMMZ/jeSjTVLr9sYUmZkH1cu+pLsr12bcg+1jZMXCDc0a0MpAoGBAPU57rOXF11dQdCpFhPucs8S77NmRrpEIeF8iHd9PyW+u63DNXekHV1LLVCqLFXFx5NXNnzglu1ovpnae94L27X2boCL2RicnbmhDQIJDgD/YaOOLV7jPvPl8StdXXZyUY/3A5pZCcSyK07VfIntY0XzvfDSjbJKuuW9mOz4SMFvAoGBAM7oX/LvXdTS3ATVwm0BQyoIGQqIWTWzI/Oq0VxHpwLjvqnH8GnPNoa78UcErD+WnMOW/JQC+q9Sky5LQxaHrZmLaLcPXgxisod7oq/kUaRkjhFmuEGaRE45ygkNLr9C9VVMHt9lxbeZpKVqPSVu7LW8sxWAprRT0n7TH477ABF/AoGARrlHi4n21hlwQtKRKHxrpicK9I15tnyx3MtCvFtl2+fvTsTu5atyQJbO4eXCVZZt4aOUdl17icrctZiagsaevhLteatbmEqK/p9hFgYwgL8mlLoLgcM+Q688Z8pMiz2bIk8WPeyR8aWE8f6GJW1OZT1PuWWwMgx1bI7KzQUqTocCgYAzh8gtttPFp2ZIhfxQLZpOo4mpB+A/8YeorghKVUYRACuCGVuU3piT4cbriwxjId2VEMuDCWLpu0UQqIni2JOxw/imbttbdlFEUNRpvhFfQfPn/Y8yN3t/iAD7VB8qX0C+p6CgvrYJTeilkdn8sq2dbYukdVAPZTjtgSNA9t5DfQKBgAklZs64WYvMkDnMcKlovNRMTgldCBMpesBq3N1P3DwEjXL6IKz6/ogMOn7C2ad4QI3nsPHNCGGjDYnaojY2uazC7OkcFOun2CL/xsL3nrP5LFcrL15ugcz3NCTPa+KLBccVNLOtXoKCALqgJ47ljxk2I9HlHQiJEChu+h3BAOIj";
try{
echo "加密数据:";$crypted_binary = "";
$privateKeyId = loadPrivateKey($privateKey);
$chunk_data = str_split($json_data, 245);
foreach($chunk_data as $data_block){
openssl_private_encrypt($data_block, $crypted, $privateKeyId, OPENSSL_PKCS1_PADDING);
$crypted_binary .= $crypted;
}
$crypted_result = QuickBase64Code::safe_base64_encode($crypted_binary);
print_r($crypted_result);
echo PHP_EOL;echo PHP_EOL;
echo "签名数据:";
$privateRsaKeyId = loadPrivateKey($privateRsaKey);
openssl_sign($json_data, $signature, $privateRsaKeyId, OPENSSL_ALGO_SHA256);
$sign_result = QuickBase64Code::safe_base64_encode($signature);
print_r($sign_result);
echo PHP_EOL;echo PHP_EOL;
}catch(Exception $e){
print $e->getMessage();
}
//===================================================================================================================//
try{
echo "解密数据:";$decrypted_result = "";
$publickKeyId = loadPublicKey($publicKey);
$decode_data = QuickBase64Code::safe_base64_decode($crypted_result);
$chunk_data = str_split($decode_data, 256);
foreach($chunk_data as $data_block){
openssl_public_decrypt($data_block, $decrypted, $publickKeyId, OPENSSL_PKCS1_PADDING);
$decrypted_result .= $decrypted;
}
print_r($decrypted_result);
echo PHP_EOL;echo PHP_EOL;
echo "验证签名:";
$publicRsaKeyId = loadPublicKey($publicRsaKey);
$decode_sign_result = QuickBase64Code::safe_base64_decode($sign_result);
$verify_result = openssl_verify($decrypted_result, $decode_sign_result, $publicRsaKeyId, OPENSSL_ALGO_SHA256);
if($verify_result == true){
echo "SUCCESS";
}else{
echo "FAILURE";
}
echo PHP_EOL;echo PHP_EOL;
}catch(Exception $e){
print $e->getMessage();
}
//===================================================================================================================//
function loadPublicKey($key){
$pem = chunk_split($key, 64, PHP_EOL);
$pem = "-----BEGIN PUBLIC KEY-----".PHP_EOL.$pem."-----END PUBLIC KEY-----".PHP_EOL;
return openssl_pkey_get_public($pem);
}
function loadPrivateKey($key){
$pem = chunk_split($key, 64, PHP_EOL);
$pem = "-----BEGIN RSA PRIVATE KEY-----".PHP_EOL.$pem."-----END RSA PRIVATE KEY-----".PHP_EOL;
return openssl_pkey_get_private($pem);
}
七、运行示例
原始数据:{"is_test":0,"channel":3366,"channel_name":"channelName","channel_uid":112355669,"channel_order":"0020260508195341811555","game_order":"QK2026050869042052718565097869312","order_no":"336620260508195338968965178","pay_time":"2026-05-08 19:53:52","amount":66,"status":0,"extras_params":"1622726932175773696_13707_1782181790395_1301_好好学习"}
加密数据:dpYGrd4dN2Q1OMvWStxivKwqFdxFaoOjqFOHArS0fqQbTuPYAHKiA3EuImIgxEW0XiADE5OhjRla7ELuPjNYYiZ02ZEbYxZvFUEvA-NNvaizwSBXVbbPjKDnnyfd3RyyZq99GahIKBEtsJzobTJMpfzKrsOra8t0wPZ8lO8g00WWNtO29NQoISHI6AqFqNWXxbWdn90Ag1oniLKjmO9GmoSUtSCoz2YxItnMBlamSa9hRVr0icjz4IYL1hsk9cyfoWSDBE7iP9ap0mQY5BxqEKO70a5clxy-Lek48kQKJVuTWrqvJEJ46HCTIow65Sk-Cjj4RwVRIG0ZXUjClI5rpUu_tit1uRakyBoUhUmhQp9EiG7K_E7ZAN0PEg1sY0_mdYbREJyDy1xKMSezspnIchFa-xj-pJ45NDcC-Grk0LjA1ua82o0PlQSs-fAl7gfgoM2DzK57lW6rtJQ49KY8FU16VjXLk7GvuhCjHChZET-dcV9YYCe9Yoz678-7dUfmqGI4gGi7ky-irvY0kTek0thh3sJmnlKj0hp19bgazhN4kPe-ahs3nRv5SwdYrfQWcSWOWmzXWGkIoXqEk6s6VMA2W5QPh7k1Re9C72BS1OCAWwYiwffFK0dLBRJAUT4llXXcjLX7s0dJwdDTZuW3j-Zvsjs0i_EQqUHiPWQAiYo
签名数据:kNZq-3ej_8kF_idY-AlEmZD0aUohzMw_UReyHzWp2OPjnTWOilRdbRBeyaYXJ7TawWbLVYJ925MPBqbk7KJDue41-fpZRp3bp6fA9Fy87Nj2u3S9ZskoIAJ-wQZ2njJp-ZII6k5QqvOmRsfEHBoZYYrEtzN1ZlBCoduxUBUMR16e6JqHjNMY9dejAYZ6bI8q87EJfiRAoPHwS_rB2rok_I5yY1TvQHBcwLjsS9VM0HHdm3O5b4xIyKf2e2D-_fQcb1D2DIISkzfDmEumAXn6pTsXU9hoePsXGLGh8BPdnhvrVhw5qLwTeA1J8fNSJoBLBVPZpJk572YPdrykDm6kwA
解密数据:{"is_test":0,"channel":3366,"channel_name":"channelName","channel_uid":112355669,"channel_order":"0020260508195341811555","game_order":"QK2026050869042052718565097869312","order_no":"336620260508195338968965178","pay_time":"2026-05-08 19:53:52","amount":66,"status":0,"extras_params":"1622726932175773696_13707_1782181790395_1301_好好学习"}
验证签名:SUCCESS
八、输出结果
成功输出
SUCCESS
李先生:13880511661
QQ:48157910
赵先生:15390049857
QQ:1077535763
孙女士:13551010407
QQ:1799614139
QQ群:698731538