由于JSON的重新排列,SpringBoot中的HMAC验证失败



我正在尝试在springBoot for REST API中使用HMAC。我从邮差那里发来的请求是

{
"name":"xyz",
"description":"hello world",
"phone":"123456",
"id":"1"
}

它到达了我的控制器,然后到达了我有功能验证HMAC的服务。在控制器中,我将签名作为请求主体中的有效载荷

@RestController
public class UserController {


@Autowired
UserInterface userInterface;

@PostMapping(value = "/" ,consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public void createUser(@RequestBody User user, @RequestHeader Map<String, String> headers) {
userInterface.hmacValidation(user, headers);
}
}
@Service
public class UserService  implements UserInterface {
public void hmacValidation(User requestBody, Map<String, String> header) {
var headerSignature = header.get("signature");
var payload = getRequestBodyAsString(requestBody);
String result = Hashing.hmacSha256("12345".getBytes(StandardCharsets.UTF_8)).hashString(payload,StandardCharsets.UTF_8).toString();

}

private String getRequestBodyAsString(User requestBody) {
var mapper = new ObjectMapper();
String payload = null;
try {
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
payload = mapper.writeValueAsString(requestBody);
} catch (JsonProcessingException e) {
}
return payload;
}
}

在这里,通过getRequestBodyAsString(User requestbody(函数,我得到的输出是一个打乱/重新排列的JSON请求,它生成不同的Signature,然后与客户端发送的Signature不匹配。

从UserObject:转换回的有效载荷

{"name":"xyz","id":"1","description":"hello world","phone":"123456"}
public class User {

private String name;
private String id;
private String description;
private String phone;
}   

客户可以按任何顺序发送请求,但无论请求在中的顺序如何,我都必须验证签名

是否有其他方法来验证HMAC?

如果要获取哈希值,则不应进行反序列化。请为请求使用字符串或字节。一旦你有了散列,稍后将其映射到你的pojo

例如:

public @ResponseBody String controllerMethod(HttpServletRequest httpReq,
HttpServletResponse httpResponse) {
BufferedReader bufferedReader;
StringBuilder sb;
sb = new StringBuilder();
bufferedReader = httpReq.getReader();
char[] charBuffer = new char[128];
int bytesRead;
while ((bytesRead = bufferedReader.read(charBuffer)) != -1) {
sb.append(charBuffer, 0, bytesRead);
}
String reqBody = sb.toString();
}

使用reqBody获取哈希值。

最新更新