Skip to content

Commit 6b45147

Browse files
authored
Fix hex conversion bug (#63)
Webhook signature validation is broken because of an error in the implementation of byte hex encoding.
1 parent 4caafda commit 6b45147

File tree

2 files changed

+34
-2
lines changed

2 files changed

+34
-2
lines changed

src/main/java/ai/nightfall/scan/WebhookSignatureValidator.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import javax.crypto.Mac;
44
import javax.crypto.spec.SecretKeySpec;
55

6-
import java.math.BigInteger;
76
import java.nio.charset.StandardCharsets;
87
import java.security.InvalidKeyException;
98
import java.security.Key;
@@ -80,7 +79,17 @@ public boolean validate(String requestBody, byte[] signingSecret, String request
8079

8180
String hashPayload = requestTime + ":" + requestBody;
8281
byte[] hashed = hmac.doFinal(hashPayload.getBytes(StandardCharsets.UTF_8));
83-
String hexHash = String.format("%032x", new BigInteger(hashed));
82+
String hexHash = bytesToHex(hashed);
8483
return hexHash.equals(requestSignature);
8584
}
85+
86+
// Java 8-16 does not have a standard Hex converter class... so as long as this SDK supports Java 8
87+
// as a minimum language level, here we are.
88+
String bytesToHex(byte[] in) {
89+
final StringBuilder builder = new StringBuilder();
90+
for (byte b : in) {
91+
builder.append(String.format("%02x", b));
92+
}
93+
return builder.toString();
94+
}
8695
}

src/test/java/ai/nightfall/scan/WebhookSignatureValidatorTest.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import static org.junit.jupiter.api.Assertions.assertFalse;
99
import static org.junit.jupiter.api.Assertions.assertTrue;
10+
import static org.junit.jupiter.api.Assertions.assertEquals;
1011

1112
/**
1213
* Unit tests for the webhook signature validator module.
@@ -62,4 +63,26 @@ public void testSignatureMismatch() {
6263
boolean result = validator.validate(reqBody, secret, incorrectSignature, timestamp);
6364
assertFalse(result);
6465
}
66+
67+
@Test
68+
public void testBytesToHex() {
69+
byte[][] tests = new byte[][]{
70+
new byte[]{-1, 1},
71+
new byte[]{6, 12, 12, 24},
72+
new byte[]{-14, -63, -34},
73+
new byte[]{0, 1, 126, 127, -128, -127, -126, -3, -2, -1},
74+
};
75+
String[] expectedResults = new String[]{
76+
"ff01",
77+
"060c0c18",
78+
"f2c1de",
79+
"00017e7f808182fdfeff"
80+
};
81+
82+
WebhookSignatureValidator validator = new WebhookSignatureValidator(reallyLongTime);
83+
for (int i = 0; i < tests.length; i++) {
84+
String actual = validator.bytesToHex(tests[i]);
85+
assertEquals(expectedResults[i], actual);
86+
}
87+
}
6588
}

0 commit comments

Comments
 (0)