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