Cap*_*rco 1 java sha256 hmac jwt
我编写了一个方法,将 JWT 作为请求并检查签名是否有效。
这是单元测试:
@Test
public void isValid() {
final JwtValidator jwtValidator = JwtValidator.getInstance();
final boolean valid = jwtValidator.isValid("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c");
Assert.isTrue(valid);
}
Run Code Online (Sandbox Code Playgroud)
这是代码:
@SneakyThrows
public boolean isValid(String extractedToken) {
final String[] tokenParts = extractedToken.split(Pattern.quote("."));
String header = tokenParts[0];
String payload = tokenParts[1];
String signature = tokenParts[2];
final byte[] calcHmacSha256 = HMAC.calcHmacSha256("your-256-bit-secret".getBytes(), (header+"."+payload).getBytes());
final String s = Base64.getEncoder().encodeToString(calcHmacSha256);
System.out.println("'" + signature + "'.equals('"+s+"')");
return signature.equals(s);
}
Run Code Online (Sandbox Code Playgroud)
日志打印两个字符串,仅相差 2 个字符,所以我觉得我已经接近“但不完全”使其工作:
'SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'.equals('SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV/adQssw5c=')
Run Code Online (Sandbox Code Playgroud)
当然存在硬编码值,因为实现尚未完成,但我现在使用https://jwt.io/中的示例值以便于使用。
谢谢!
编辑1:
public class JwtValidatorTest {
@Test
public void isValid() {
byte[] header64 = Base64.getEncoder().encode("{\"alg\":\"HS256\",\"typ\":\"JWT\"}".getBytes());
byte[] payload64 = Base64.getEncoder().encode("{\"sub\":\"1234567890\",\"name\":\"John Doe\",\"iat\":1516239022}".getBytes());
final byte[] calcHmacSha256 = HMAC.calcHmacSha256("your-256-bit-secret".getBytes(), (header64+"."+payload64).getBytes());
final String signature64 = Base64.getEncoder().encodeToString(calcHmacSha256);
final String input = header64 + "." + payload64 + "." + signature64;
final JwtValidator jwtValidator = JwtValidator.getInstance();
final boolean valid = jwtValidator.isValid(input);
Assert.isTrue(valid);
}
}
Run Code Online (Sandbox Code Playgroud)
差异只是由于这里使用的编码不同造成的。您使用了 Base64 编码,但原始签名是Base64Url编码的。根据 RFC7519,Base64Url 编码是JWT 的标准编码:
每个部分都包含一个 base64url 编码的值
=Base64Url 编码末尾没有填充 ( ),字符+和/被替换为-和_。
这段代码应该可以解决这个问题:
final String s = Base64.getUrlEncoder().withoutPadding().encodeToString(calcHmacSha256);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
889 次 |
| 最近记录: |