+1
-1
@@ -79,7 +79,7 @@ public class WebhookSendController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. 서명 검증
|
// 2. 서명 검증
|
||||||
boolean isValid = webhookReceiveService.verifySignature(rawPayload, signature);
|
boolean isValid = webhookReceiveService.verifySignature(rawPayload, signature, "");
|
||||||
if (!isValid) {
|
if (!isValid) {
|
||||||
log.warn("[Webhook] 수신 거부 - 서명 불일치 / eventType: {}", eventType);
|
log.warn("[Webhook] 수신 거부 - 서명 불일치 / eventType: {}", eventType);
|
||||||
return ResponseEntity
|
return ResponseEntity
|
||||||
|
|||||||
+3
-4
@@ -20,7 +20,6 @@ public class WebhookReceiveService {
|
|||||||
private final ObjectMapper objectMapper;
|
private final ObjectMapper objectMapper;
|
||||||
|
|
||||||
|
|
||||||
private String secretKey = "HW8JtFpkPmQqsVmr0Rb81P4qDypaNIVbGf3ZNMMPfyerhOHshoKABLaMBo1HA4BldTxhw1NjYmVnoPu9IIV7cyRXjecL3b2UctyR7DnVaJausltZLLr8Qm4Bzs4wRmgf";
|
|
||||||
|
|
||||||
private static final String HMAC_ALGORITHM = "HmacSHA256";
|
private static final String HMAC_ALGORITHM = "HmacSHA256";
|
||||||
private static final long TIMESTAMP_LIMIT = 5 * 60 * 1000L; // 5분 (ms)
|
private static final long TIMESTAMP_LIMIT = 5 * 60 * 1000L; // 5분 (ms)
|
||||||
@@ -33,14 +32,14 @@ public class WebhookReceiveService {
|
|||||||
* 수신된 서명과 payload 로 재계산한 서명을 비교
|
* 수신된 서명과 payload 로 재계산한 서명을 비교
|
||||||
* 헤더값 형식 : "sha256={hex값}"
|
* 헤더값 형식 : "sha256={hex값}"
|
||||||
*/
|
*/
|
||||||
public boolean verifySignature(String rawPayload, String receivedSignature) {
|
public boolean verifySignature(String rawPayload, String receivedSignature, String secretKey) {
|
||||||
try {
|
try {
|
||||||
// "sha256=" 접두어 제거
|
// "sha256=" 접두어 제거
|
||||||
String receivedHex = receivedSignature.startsWith("sha256=")
|
String receivedHex = receivedSignature.startsWith("sha256=")
|
||||||
? receivedSignature.substring(7)
|
? receivedSignature.substring(7)
|
||||||
: receivedSignature;
|
: receivedSignature;
|
||||||
|
|
||||||
String expectedHex = generateSignature(rawPayload);
|
String expectedHex = generateSignature(rawPayload, secretKey);
|
||||||
|
|
||||||
// 타이밍 공격 방지 : MessageDigest.isEqual 사용
|
// 타이밍 공격 방지 : MessageDigest.isEqual 사용
|
||||||
return MessageDigest.isEqual(
|
return MessageDigest.isEqual(
|
||||||
@@ -124,7 +123,7 @@ public class WebhookReceiveService {
|
|||||||
/* 공통 유틸 */
|
/* 공통 유틸 */
|
||||||
/* ------------------------------------------------------------------ */
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
private String generateSignature(String payload) throws Exception {
|
private String generateSignature(String payload, String secretKey) throws Exception {
|
||||||
Mac mac = Mac.getInstance(HMAC_ALGORITHM);
|
Mac mac = Mac.getInstance(HMAC_ALGORITHM);
|
||||||
SecretKeySpec keySpec = new SecretKeySpec(
|
SecretKeySpec keySpec = new SecretKeySpec(
|
||||||
secretKey.getBytes(StandardCharsets.UTF_8), HMAC_ALGORITHM);
|
secretKey.getBytes(StandardCharsets.UTF_8), HMAC_ALGORITHM);
|
||||||
|
|||||||
@@ -90,7 +90,14 @@ public class WebhookService {
|
|||||||
wr.setData(new ArrayList<String>());
|
wr.setData(new ArrayList<String>());
|
||||||
return wr;
|
return wr;
|
||||||
});
|
});
|
||||||
((List<String>) resultMap.get(key).getData()).add(t.get(api.id.apiId));
|
|
||||||
|
WebhookSendRequest wsr = resultMap.get(key);
|
||||||
|
if (wsr != null) {
|
||||||
|
List<String> list = (List<String>) wsr.getData();
|
||||||
|
if (list != null) {
|
||||||
|
list.add(t.get(api.id.apiId));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ArrayList<>(resultMap.values());
|
return new ArrayList<>(resultMap.values());
|
||||||
|
|||||||
Reference in New Issue
Block a user