java SDK 示例
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.*;
public class WLWSigner {
/**
* 生成签名
*/
public static String generateSignature(
String method,
String path,
Map<String, String> params,
String secretKey
) {
try {
// 1. 排序参数(排除 signature)
List<String> keys = new ArrayList<>();
for (String key : params.keySet()) {
if (!"signature".equals(key)) {
keys.add(key);
}
}
Collections.sort(keys);
// 2. 构造参数字符串 key=value&key=value
StringBuilder paramBuilder = new StringBuilder();
for (int i = 0; i < keys.size(); i++) {
String key = keys.get(i);
paramBuilder.append(key)
.append("=")
.append(params.get(key));
if (i < keys.size() - 1) {
paramBuilder.append("&");
}
}
// 3. 构造 signStr
String signStr = method
+ path
+ params.get("timestamp")
+ params.get("nonce");
if (paramBuilder.length() > 0) {
signStr += paramBuilder.toString();
}
// 4. HMAC-SHA256
Mac mac = Mac.getInstance("HmacSHA256");
SecretKeySpec secretKeySpec = new SecretKeySpec(
secretKey.getBytes(StandardCharsets.UTF_8),
"HmacSHA256"
);
mac.init(secretKeySpec);
byte[] rawHmac = mac.doFinal(signStr.getBytes(StandardCharsets.UTF_8));
// 5. 转 hex
return bytesToHex(rawHmac);
} catch (Exception e) {
throw new RuntimeException("生成签名失败", e);
}
}
/**
* byte[] 转 16进制字符串
*/
private static String bytesToHex(byte[] bytes) {
StringBuilder hex = new StringBuilder(bytes.length * 2);
for (byte b : bytes) {
String s = Integer.toHexString(0xff & b);
if (s.length() == 1) {
hex.append('0');
}
hex.append(s);
}
return hex.toString();
}
}