fix: tolerate lingxian callback signing variants

This commit is contained in:
hy001 2026-05-12 11:19:40 +08:00
parent 3a01a490ab
commit 93c39f77cf

View File

@ -51,7 +51,9 @@ import com.red.circle.tool.core.text.StringUtils;
import com.red.circle.tool.crypto.SecurityUtils; import com.red.circle.tool.crypto.SecurityUtils;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@ -102,10 +104,10 @@ public class GameHkysRestController {
return new HkysResponse<HkysUserProfileResponse>() return new HkysResponse<HkysUserProfileResponse>()
.setErrorCode(HyksErrorEnum.PARAM_ERROR.getErrorCode()); .setErrorCode(HyksErrorEnum.PARAM_ERROR.getErrorCode());
} }
String sign = SecurityUtils.md5(Stream.of(cmd.getGameId(), cmd.getUid(), cmd.getToken(), cmd.getRoomId(), if (!verifyLingxianUserInfoSign(cmd)) {
resolveLingxianSignKey(cmd.getToken())).filter(Objects::nonNull).map(String::valueOf) log.warn("lingxian getUserInfo sign verify failed, uid={}, gameId={}, roomId={}, sysOrigin={}, tokenLength={}",
.collect(Collectors.joining(""))); cmd.getUid(), cmd.getGameId(), cmd.getRoomId(), resolveSysOriginQuietly(cmd.getToken()),
if (!sign.equals(cmd.getSign())) { cmd.getToken() == null ? 0 : cmd.getToken().length());
return new HkysResponse<HkysUserProfileResponse>().setErrorCode(HyksErrorEnum.SIGN_VERIFY_FAIL.getErrorCode()); return new HkysResponse<HkysUserProfileResponse>().setErrorCode(HyksErrorEnum.SIGN_VERIFY_FAIL.getErrorCode());
} }
@ -125,10 +127,10 @@ public class GameHkysRestController {
|| Objects.isNull(cmd.getType()) || Objects.isNull(cmd.getCoin())) { || Objects.isNull(cmd.getType()) || Objects.isNull(cmd.getCoin())) {
return new HkysResponse<JSONObject>().setErrorCode(HyksErrorEnum.PARAM_ERROR.getErrorCode()); return new HkysResponse<JSONObject>().setErrorCode(HyksErrorEnum.PARAM_ERROR.getErrorCode());
} }
String sign = SecurityUtils.md5(Stream.of(cmd.getOrderId(), cmd.getGameId(), cmd.getRoundId(), cmd.getUid(), if (!verifyLingxianUpdateBalanceSign(cmd)) {
cmd.getCoin(), cmd.getType(), cmd.getToken(), cmd.getWinId(), cmd.getRoomId(), resolveLingxianSignKey(cmd.getToken())) log.warn("lingxian updateBalance sign verify failed, uid={}, gameId={}, orderId={}, roomId={}, sysOrigin={}, tokenLength={}",
.filter(Objects::nonNull).map(String::valueOf).collect(Collectors.joining(""))); cmd.getUid(), cmd.getGameId(), cmd.getOrderId(), cmd.getRoomId(), resolveSysOriginQuietly(cmd.getToken()),
if (!sign.equals(cmd.getSign())) { cmd.getToken() == null ? 0 : cmd.getToken().length());
return new HkysResponse<JSONObject>().setErrorCode(HyksErrorEnum.SIGN_VERIFY_FAIL.getErrorCode()); return new HkysResponse<JSONObject>().setErrorCode(HyksErrorEnum.SIGN_VERIFY_FAIL.getErrorCode());
} }
@ -226,12 +228,72 @@ public class GameHkysRestController {
} }
private String resolveLingxianSignKey(String token) { private String resolveLingxianSignKey(String token) {
String sysOrigin = resolveSysOriginQuietly(token); List<String> keys = lingxianSignKeys(token);
String appKey = gameListConfigService.getActiveLingxianAppKey(sysOrigin); return keys.isEmpty() ? "" : keys.get(0);
if (StringUtils.isNotBlank(appKey)) { }
return appKey;
private boolean verifyLingxianUserInfoSign(GameLxwlUserInfoCmd cmd) {
for (String token : lingxianTokenCandidates(cmd.getToken())) {
for (String key : lingxianSignKeys(token)) {
String sign = SecurityUtils.md5(Stream.of(cmd.getGameId(), cmd.getUid(), token, cmd.getRoomId(), key)
.filter(Objects::nonNull).map(String::valueOf).collect(Collectors.joining("")));
if (sign.equalsIgnoreCase(cmd.getSign())) {
return true;
}
}
} }
return gameHkysProperties.getSignKey(); return false;
}
private boolean verifyLingxianUpdateBalanceSign(GameLxwlUpdateBalanceCmd cmd) {
for (String token : lingxianTokenCandidates(cmd.getToken())) {
for (String key : lingxianSignKeys(token)) {
String sign = SecurityUtils.md5(Stream.of(cmd.getOrderId(), cmd.getGameId(), cmd.getRoundId(), cmd.getUid(),
cmd.getCoin(), cmd.getType(), token, cmd.getWinId(), cmd.getRoomId(), key)
.filter(Objects::nonNull).map(String::valueOf).collect(Collectors.joining("")));
if (sign.equalsIgnoreCase(cmd.getSign())) {
return true;
}
}
}
return false;
}
private List<String> lingxianSignKeys(String token) {
List<String> keys = new ArrayList<>();
addIfNotBlank(keys, gameListConfigService.getActiveLingxianAppKey(resolveSysOriginQuietly(token)));
addIfNotBlank(keys, gameHkysProperties.getSignKey());
return keys;
}
private List<String> lingxianTokenCandidates(String token) {
List<String> tokens = new ArrayList<>();
if (StringUtils.isBlank(token)) {
tokens.add(null);
return tokens;
}
addTokenCandidate(tokens, token);
addTokenCandidate(tokens, SecurityUtils.urlDecode(token));
return tokens;
}
private void addTokenCandidate(List<String> tokens, String token) {
if (StringUtils.isBlank(token)) {
return;
}
addIfNotBlank(tokens, token);
addIfNotBlank(tokens, trimTokenPadding(token));
}
private String trimTokenPadding(String token) {
return token == null ? "" : token.trim().replaceAll("=+$", "");
}
private void addIfNotBlank(List<String> values, String value) {
if (StringUtils.isBlank(value) || values.contains(value)) {
return;
}
values.add(value);
} }
private String resolveSysOriginQuietly(String token) { private String resolveSysOriginQuietly(String token) {