为了高系统的安全性并且有效隐藏接口信息,我们决定采用动态化接口地址的方式来防止被恶意扫描和利用。Spring框架提供了便捷的Path参数功能,使得动态化接口地址的实现变得轻而易举。
这个设计的思路来自TOTP(基于时间的一次性密码)技术,通常用于双因素验证的情况,比如游戏的动态令牌。借鉴这个思路,通过计算当前时间戳,可以在一段时间内生成相同的结果,这个结果被用于作为Path参数的校验,如果Path参数值和服务端计算出来的不同则返回404模拟接口不存在。并且Path参数应该允许5秒左右的延迟。
代码大概如下:
@RestController
public class DynamicPathController {
private static final String SECRET_KEY = "your-secret-key";
private static final long TIME_STEP = 30;
private static final long WINDOW_SIZE = 5;
@GetMapping("/api/{path}")
public String getApi(@PathVariable("path") String path) {
if (isValidPath(path)) {
// 处理实际的接口逻辑
return ResponseEntity.ok("Valid path parameter received");
} else {
// 返回404状态码,模拟接口不存在
return ResponseEntity.status(HttpStatus.NOT_FOUND);
}
}
private boolean isValidPath(String path) {
long timestamp = System.currentTimeMillis();
return path.equals(generatePath(timestamp)) || path.equals(generatePath(timestamp - WINDOW_SIZE * 1000));
}
private String generatePath(long timestamp) {
long timeSlice = timestamp / TIME_STEP;
String message = SECRET_KEY + timeSlice;
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest(message.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b : hash) {
sb.append(String.format("%02x", b));
}
return sb.toString();
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("无法生成Path参数", e);
}
}
}
这种方式提高了一部分安全性,但仅限于防止恶意扫描的情况,如果是客户端被逆向,这种方式就失去作用了,需要使用更多的安全措施来进行安全保障。
0 条评论