我正在尝试在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
获取哈希值。