为了高系统的安全性并且有效隐藏接口信息,我们决定采用动态化接口地址的方式来防止被恶意扫描和利用。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 条评论

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用 * 标注