test: verify lingxing track key vector

This commit is contained in:
2026-09-22 13:33:43 +08:00
parent ab68334af3
commit 2813be3581
2 changed files with 24 additions and 3 deletions
@@ -87,15 +87,18 @@ public class LingxingDirectClient {
}
private static String text(JsonNode node, String key) { return node.path(key).isMissingNode() ? null : node.path(key).asText(null); }
private static java.math.BigDecimal decimal(JsonNode node, String key) { return node.path(key).isNumber() ? node.path(key).decimalValue() : null; }
private String trackKey(String method, String json) {
if (properties.getTrackKeyV2SecretBase64() == null || properties.getTrackKeyV2SecretBase64().isBlank()) throw new IllegalStateException("未配置领星 Track-Key v2 密钥");
static String buildTrackKey(String method, String json, String secretBase64) {
if (secretBase64 == null || secretBase64.isBlank()) throw new IllegalStateException("未配置领星 Track-Key v2 密钥");
try {
byte[] digest = MessageDigest.getInstance("SHA-256").digest(json.getBytes(StandardCharsets.UTF_8));
StringBuilder hex = new StringBuilder(); for (byte b : digest) hex.append(String.format(Locale.ROOT, "%02x", b));
Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(Base64.getDecoder().decode(properties.getTrackKeyV2SecretBase64()), "HmacSHA256"));
byte[] key = Base64.getDecoder().decode(secretBase64);
if (key.length != 44) throw new IllegalStateException("领星 Track-Key v2 密钥解码后必须是 44 字节");
Mac mac = Mac.getInstance("HmacSHA256"); mac.init(new SecretKeySpec(key, "HmacSHA256"));
return "v2:" + Base64.getEncoder().encodeToString(mac.doFinal((method.toUpperCase(Locale.ROOT) + hex).getBytes(StandardCharsets.UTF_8)));
} catch (Exception ex) { throw new IllegalStateException("领星 Track-Key 生成失败", ex); }
}
private String trackKey(String method, String json) { return buildTrackKey(method, json, properties.getTrackKeyV2SecretBase64()); }
private String canonical(JsonNode node) throws Exception { return mapper.writeValueAsString(sort(node)); }
private JsonNode sort(JsonNode node) {
if (!node.isObject()) return node;
@@ -0,0 +1,18 @@
package com.baiyue.firstleg.lingxing;
import org.junit.jupiter.api.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assumptions.assumeTrue;
class LingxingTrackKeyVectorTest {
@Test
void matchesNodeTrackKeyV2VectorWhenSecretIsProvided() {
String secret = System.getenv("LINGXING_TRACK_KEY_V2_SECRET_BASE64");
assumeTrue(secret != null && !secret.isBlank(),
"Set LINGXING_TRACK_KEY_V2_SECRET_BASE64 to run the protected vector test");
String body = "{\"businessType\":\"oms\",\"deviceFingerprint\":\"12345678\",\"deviceInfo\":\"UA | 1920x1080 | Asia/Shanghai\",\"loginAccount\":\"demo\",\"loginFlowId\":\"00112233445566778899aabbccddeeff\",\"password\":\"secret\"}";
assertThat(LingxingDirectClient.buildTrackKey("POST", body, secret))
.isEqualTo("v2:IbVx50WEXAxeGsc/66LjqC0WSxT2ZF0K4V4JYU/LkYw=");
}
}