嘿,伙计们,我对java非常陌生,我无法成功地用PS256来验证一个带有弹性城堡的JWT签名。它总是提前返回一个假值.Thk!
这是我的示例代码:
String cert =
"-----BEGIN CERTIFICATE-----\n" +
"MIIDXTCCAkWgAwIBAgIEf7cAqTANBgkqhkiG9w0BAQsFADBfMQswCQYDVQQGEwJS\n" +
"bzESMBAGA1UECBMJQnVjaGFyZXN0MRIwEAYDVQQHEwlCdWNoYXJlc3QxDDAKBgNV\n" +
"BAoTA0lTUzEMMAoGA1UECxMDSVNTMQwwCgYDVQQDEwNJU1MwHhcNMjAwMjA2MTM1\n" +
"NTEwWhcNMjAwNTA2MTM1NTEwWjBfMQswCQYDVQQGEwJSbzESMBAGA1UECBMJQnVj\n" +
"aGFyZXN0MRIwEAYDVQQHEwlCdWNoYXJlc3QxDDAKBgNVBAoTA0lTUzEMMAoGA1UE\n" +
"CxMDSVNTMQwwCgYDVQQDEwNJU1MwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\n" +
"AoIBAQDhvsOgiLgZcQRzioyWZOfObGsbeMAtZXph1LlgMr+MYmXHLKQa7v1Xo/3o\n" +
"JmzFfUj7pUsVo6og3j5n7CFpxvQ6CudVL2Tml+LHvRYy9jHs0dk44SRyEiMWYKw+\n" +
"l6RttXSKrLyNLa+U8FWzQehkzsFJU4HsVxsoYkrZZP2WEKyHIG7ejFGdafRUv2GO\n" +
"YRUNDzTcsDsy9M2ulMbYHj1Lzi3/sQ2N7A1xcEC7Bi6A012XOOPBpsNHmnZzZLpA\n" +
"FZMCdb/8dTb9XHxDhEBdB5EsmDyCwS+cgj83tWxQIpT4ZU70uygXT28X1NgG0S7d\n" +
"qVWZ3Pvocsttg8Eu+7SXO8K4uLOdAgMBAAGjITAfMB0GA1UdDgQWBBT1x4g7+S4Q\n" +
"4p/jJKkLid/+m1U/ZDANBgkqhkiG9w0BAQsFAAOCAQEAuNRTUrDrbC1Iv9ECjMmA\n" +
"qKkyT56lb3JdhpAP0O9yT/F3pFkUywikJPSc83m9lHc8KRI3KINspspj2XePDh9b\n" +
"6oLXZwFG/tv4I8j3fKxpwO9BcTMyOoYRynHl8PxePWA+Xtg3P/yVhDqZBaTqAifB\n" +
"A5QyN8AKh+Nt1mySCODFp76wJjvnCXdk1M7jGW38U92kNtC6I8Pv6li9xuRKZGyT\n" +
"B9qQqsop3LtxS4fy719Gyytzc23B8NwFdLzPM0P0iJiz7aGU7uLsdBGe92GRrHf8\n" +
"9A9DlBnqQwBLesw/fPzLt67hUnUaFg71rP1ZbFcT/yRhH8IEQhaQ29lSXmZjG6Tz\n" +
"PA==\n" +
"-----END CERTIFICATE-----";
CertificateFactory certFactory = CertificateFactory.getInstance("X.509");
ByteArrayInputStream bytes = new ByteArrayInputStream(cert.getBytes());
X509Certificate certificate1 = (X509Certificate) certFactory.generateCertificate(bytes);
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
String jwtS = "eyJ0eXAiOiJKV1QiLCJhbGciOiJQUzI1NiJ9.eyJjdXN0b21lcklkIjoiYSIsImFjY291bnRzIjoiYyIsImNvdW50cnlDb2RlIjoiYiJ9.KMrdAKLjQkQCE5GRa39pLdmAGcwIgNVreRsDf_jbQLDWeRoH_ChxZF9X8lV9wwJIJfC3mjH2sDwwnsn0Dw5q3OpM83VWDbHeQ9899_kfV1XDxdoUB54xGUsC95w3CP5eNXthLWn58l8areCATK-TesMnu1BNZ5jzBQohqns_a1NUDP0cWweWp477Fj2-nmuceNO0OihqnZ08gCdaXmgdrX73nlf9WNEXcgGpWQMhatdzB43vKBMBkfF1PudN-gm4s9QBYcGWRjZJrqUKRPbYZuLCs39N4WOX896nWaTGyiVCwcdfV1SDSGafqE_PfNu5kUezm31jy2Uk0p-KcyoSdQ";
JWT jwt = JWTParser.parse(jwtS);
SignedJWT jwsObject = (SignedJWT) jwt;
Base64URL signature = jwsObject.getSignature();
Signature sig = Signature.getInstance("SHA256withRSAandMGF1","BC");
System.out.println("Signature: " + signature.toJSONString());
sig.initVerify(certificate1);
sig.update(signature.decode());
boolean flagSig = sig.verify(jwsObject.getSignature().decode());
System.out.println("Signature is valid: " + flagSig);
发布于 2020-02-06 15:19:43
这就是你错的地方:
sig.update(signature.decode());
您正在尝试验证签名字节本身上的签名。
更新
根据初始化的类型,这将更新要签名或验证的字节。
在您的示例中,要验证的数据是编码的header.payload
,因此:
eyJ0eXAiOiJKV1QiLCJhbGciOiJQUzI1NiJ9.eyJjdXN0b21lcklkIjoiYSIsImFjY291bnRzIjoiYyIsImNvdW50cnlDb2RlIjoiYiJ9
如果您使用的是JWT库,它应该提供一个验证方法,使用它会更安全。
另外,如果您使用的是Java11+,那么就有对RSASSA-PSS
的支持。这消除了使用BouncyCastle的需要。
https://stackoverflow.com/questions/60097130
复制相似问题