環境
Version | |
---|---|
Java | 11 |
Spring Boot | 2.5.6 |
JUnit | 5.7.2 |
HS256の署名検証
仕様
HS256のID Tokenは、client_secret
を鍵として用いて署名されている。
やり方
ここ(JSON Web Signature (JWS)
Example JWS using HMAC SHA-256)をお手本にするのが良さそう。
コード
@Slf4j
@SpringBootTest
public class JWTSignatureVerifyTest {
// TODO 調達したsecretで置き換えてください。
@Value("${spring.security.oauth2.client.registration.dummy.client-secret}")
private String secret;
@Test
public void test() throws NoSuchAlgorithmException, InvalidKeyException {
// TODO 調達したHS256署名されたIDトークンで置き換えてください
String idToken = "dummy";
var signatureStart = idToken.lastIndexOf(".") + 1;
var bodyEnd = idToken.lastIndexOf(".");
var headAndBody = idToken.substring(0, bodyEnd);
var signature = idToken.substring(signatureStart);
var jwtInput = headAndBody.getBytes(StandardCharsets.UTF_8);
String algo = "HmacSHA256";
SecretKeySpec sk = new SecretKeySpec(secret.getBytes(), algo);
Mac mac = Mac.getInstance(algo);
mac.init(sk);
log.info("headAndBody:{}", headAndBody);
byte[] mac_bytes = mac.doFinal(jwtInput);
byte[] encoded = Base64.getEncoder().encode(mac_bytes);
log.info("original signature:\t{}", signature);
var encodedString = new String(encoded);
log.info("encodedString:\t{}", encodedString);
var encodedStringReplaced = encodedString.replaceAll("\\+", "-").replace("/", "_").replaceAll("=");
log.info("encodedString replaced:\t{}", encodedStringReplaced);
Assertions.assertThat(encodedStringReplaced).isEqualTo(signature);
}
}
最後の方の.replaceAll("\\+", "-").replace("/", "_")
について
rfc7515 appendig-Cに詳しくある。
最後の方のreplaceAll("=","")
について
rfc7515 appendig-Cに詳しくある。
Base64エンコーディングすると、規定長にするために=
がパディングされる。
参考資料
JavaでHMAC-SHA256を計算する
JSON Web Signature (JWS)
Example JWS using HMAC SHA-256
Auth0 validate-json-web-tokens
oauth2login-advanced-idtoken-verify
JSON Web Token (JWT)
Algorithms