💻 签名函数代码示例
Java
签名函数实现
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;
import java.util.Comparator;
import java.util.stream.Collectors;
public class SignGenerator {
private static final String ALGORITHM = "HmacSHA256";
/**
* 生成签名
* @param parameters 签名参数列表
* @param accessToken 访问令牌
* @return 签名字符串
*/
public static String sign(List<Pair<String, String>> parameters, String accessToken) throws Exception {
// 1. 将参数按 key=value 格式拼接
// 2. 按字典序升序排序
// 3. 用 & 连接形成待签名字符串
String data = parameters.stream()
.map(p -> String.format("%s=%s", p.getKey(), p.getValue()))
.sorted(Comparator.comparing(Function.identity()))
.collect(Collectors.joining("&"));
// 4. 使用 HMAC-SHA256 加密
Mac mac = Mac.getInstance(ALGORITHM);
mac.init(new SecretKeySpec(accessToken.getBytes(StandardCharsets.UTF_8), ALGORITHM));
byte[] rawHmac = mac.doFinal(data.getBytes(StandardCharsets.UTF_8));
// 5. Base64 编码
String rawSign = Base64.getEncoder().encodeToString(rawHmac);
// 6. 将 +、/、= 替换为 B
return rawSign.replaceAll("[+/=]", "B");
}
// 简单的 Pair 类
public static class Pair<K, V> {
private K key;
private V value;
public Pair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() { return key; }
public V getValue() { return value; }
}
}
📝 调用示例
// 创建参数列表
List<SignGenerator.Pair<String, String>> params = new ArrayList<>();
params.add(new SignGenerator.Pair<>("ts", "1736739534331"));
params.add(new SignGenerator.Pair<>("app_id", "bili388fh0g748hdj"));
params.add(new SignGenerator.Pair<>("amount", "100"));
params.add(new SignGenerator.Pair<>("product_type", "1"));
// 生成签名
String accessToken = "DsI5UxNG5NWuYTJlNDg1NGFkMzRl9Ukp";
String signature = SignGenerator.sign(params, accessToken);
System.out.println("签名结果: " + signature);
PHP
签名函数实现
<?php
class SignGenerator {
private const ALGORITHM = 'sha256';
/**
* 生成签名
* @param array $parameters 签名参数数组(关联数组)
* @param string $accessToken 访问令牌
* @return string 签名字符串
*/
public static function sign(array $parameters, string $accessToken): string {
// 1. 将参数按 key=value 格式拼接
$mappedParams = [];
foreach ($parameters as $key => $value) {
$mappedParams[] = $key . '=' . $value;
}
// 2. 按字典序升序排序
sort($mappedParams);
// 3. 用 & 连接形成待签名字符串
$data = implode('&', $mappedParams);
// 4. 使用 HMAC-SHA256 加密
$rawHmac = hash_hmac(self::ALGORITHM, $data, $accessToken, true);
// 5. Base64 编码
$rawSign = base64_encode($rawHmac);
// 6. 将 +、/、= 替换为 B
return str_replace(['+', '/', '='], 'B', $rawSign);
}
}
?>
📝 调用示例
<?php
// 创建参数数组
$parameters = [
'ts' => '1736739534331',
'app_id' => 'bili388fh0g748hdj',
'amount' => '100',
'product_type' => '1'
];
// 生成签名
$accessToken = 'DsI5UxNG5NWuYTJlNDg1NGFkMzRl9Ukp';
$signature = SignGenerator::sign($parameters, $accessToken);
echo "签名结果: " . $signature . "\n";
?>
JavaScript
签名函数实现(需引入 crypto-js)
// 引入 crypto-js 库
// npm install crypto-js
// 或在浏览器中引入: <script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
const CryptoJS = require('crypto-js'); // Node.js 环境
/**
* 生成签名
* @param {Object} parameters - 签名参数对象
* @param {string} accessToken - 访问令牌
* @returns {string} 签名字符串
*/
function generateSign(parameters, accessToken) {
// 1. 按字典序排序
const sortedKeys = Object.keys(parameters).sort();
// 2. 拼接 key=value
const pairs = sortedKeys.map(key => `${key}=${parameters[key]}`);
// 3. 用 & 连接形成待签名字符串
const data = pairs.join('&');
// 4. 使用 HMAC-SHA256 加密
const hmac = CryptoJS.HmacSHA256(data, accessToken);
// 5. Base64 编码
const base64 = CryptoJS.enc.Base64.stringify(hmac);
// 6. 将 +、/、= 替换为 B
const sign = base64.replace(/[+/=]/g, 'B');
return sign;
}
📝 调用示例
// 创建参数对象
const parameters = {
ts: '1736739534331',
app_id: 'bili388fh0g748hdj',
amount: '100',
product_type: '1'
};
// 生成签名
const accessToken = 'DsI5UxNG5NWuYTJlNDg1NGFkMzRl9Ukp';
const signature = generateSign(parameters, accessToken);
console.log('签名结果:', signature);
⚠️ 重要提示
- 所有参数值必须转换为字符串类型
- 空字符串('')的参数不参与签名
- 参数必须按字典序(ASCII码)升序排序
- 布尔类型参数必须是小写的 true/false
- 数组、List等类型需要通过逗号(,)序列化为单一字符串
- access_token 请妥善保管,不要泄露