如何使用RSA私钥解密JWT

时间:2017-04-05 18:16:26

标签: java spring rsa jwt jose

我们有一个远程应用程序向我们发送JWT。他们使用“RSA-OAEP-256”算法和“A256CBC-HS512”加密和我们的公钥对令牌进行编码,现在我正在尝试对其进行解密并解析声明。我使用openssl rsa -in <myPrivateKey> -pubout -out <myPublicKey>生成了密钥,然后根据此SO post的建议将myPrivateKey转换为.der。按照nimbus的指南,我想出了以下内容。

    @Test
public void testDecryptJwtWithRsa() {
String filename = <myPrivateKey.der>;
String tokenString = <encryptedTokenString>;
    try {
        byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        PrivateKey pk = kf.generatePrivate(spec);
        byte[] encodedPk = pk.getEncoded();
        JWEObject jweObject = JWEObject.parse(tokenString);
        jweObject.decrypt(new DirectDecrypter(encodedPk));
        SignedJWT signedJWT = jweObject.getPayload().toSignedJWT();
        String jsonToken = jweObject.getPayload().toJSONObject().toJSONString();
        System.out.println(jsonToken);

    } catch (Exception e) {
        System.out.println(e.getMessage());
        Assert.fail();
    }
}

java.security.PrivateKey正确解析,但我在jweObject.decrypt(new DirectDecrypter(encodedPk));收到错误:

The Content Encryption Key length must be 128 bits (16 bytes), 192 bits (24 bytes), 256 bits (32 bytes), 384 bits (48 bytes) or 512 bites (64 bytes)

此外,在调试器中,我可以看到jwe.payload为空,但我不知道在解密之前是否应填充此内容。

我是否需要以不同的方式生成密钥,或者是否有另外一个省略的步骤?我是否需要在某处指定算法,或使用不同的解密器方法/类?

1 个答案:

答案 0 :(得分:1)

事实证明,我使用的方法是使用对称密钥而不是公共/私有来解密。以下处理成功解密,并允许我查看声明。

    @Test
public void decryptBlazemeterJwt() {
    try {
        byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        PrivateKey pk = kf.generatePrivate(spec);
        EncryptedJWT jwt = EncryptedJWT.parse(tokenString);
        RSADecrypter decrypter = new RSADecrypter(pk);
        jwt.decrypt(decrypter);
    } catch (Exception e) {
        System.out.println(e.getMessage());
        Assert.fail();
    }
}