使用Java库创建使用RSA加密的JWT(Json Web Token)

3

我希望开发一个JWT应用程序,使用"Nimbus JOSE+JWT"库进行RSA加密。 我正在寻找示例代码。

我想使用以下Maven依赖项:

<dependency>
    <groupId>com.nimbusds</groupId>
    <artifactId>nimbus-jose-jwt</artifactId>
    <version>3.10</version>
</dependency>

注意:请始终使用Maven中央仓库的最新版本。
3个回答

3
如果您正在使用“Nimbus Jose JWT”的最新版本4.23,则API中有一些小的更改。
<dependency>
    <groupId>com.nimbusds</groupId>
    <artifactId>nimbus-jose-jwt</artifactId>
    <version>4.23</version>
</dependency>

我已经提供以下代码以供参考:

public class JwtJoseExample {
    public static void main(String[] args) {
        KeyPairGenerator keyPairGenerator;
        try {
            keyPairGenerator = KeyPairGenerator.getInstance("RSA");

            keyPairGenerator.initialize(1024);

            // generate the key pair
            KeyPair keyPair = keyPairGenerator.genKeyPair();

            // create KeyFactory and RSA Keys Specs
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            RSAPublicKeySpec publicKeySpec = keyFactory.getKeySpec(keyPair.getPublic(), RSAPublicKeySpec.class);
            RSAPrivateKeySpec privateKeySpec = keyFactory.getKeySpec(keyPair.getPrivate(), RSAPrivateKeySpec.class);

            // generate (and retrieve) RSA Keys from the KeyFactory using Keys Specs
            RSAPublicKey publicRsaKey = (RSAPublicKey) keyFactory.generatePublic(publicKeySpec);
            RSAPrivateKey privateRsaKey  = (RSAPrivateKey) keyFactory.generatePrivate(privateKeySpec);

            JWTClaimsSet.Builder claimsSet = new JWTClaimsSet.Builder();
            claimsSet.issuer("https://my-auth-server.com");
            claimsSet.subject("John Kerr");
            claimsSet.audience(getAudience());
            claimsSet.expirationTime(new Date(new Date().getTime() + 1000*60*10));
            claimsSet.notBeforeTime(new Date());
            claimsSet.jwtID(UUID.randomUUID().toString());

            System.out.println("--------------------------");
            System.out.println("Claim Set : \n"+claimsSet.build());

            // create the JWT header and specify:
            //  RSA-OAEP as the encryption algorithm
            //  128-bit AES/GCM as the encryption method
            JWEHeader header = new JWEHeader(JWEAlgorithm.RSA_OAEP, EncryptionMethod.A128GCM);

            // create the EncryptedJWT object
            EncryptedJWT jwt = new EncryptedJWT(header, claimsSet.build());

            // create an RSA encrypter with the specified public RSA key
            RSAEncrypter encrypter = new RSAEncrypter(publicRsaKey);

            // do the actual encryption
            jwt.encrypt(encrypter);

            // serialize to JWT compact form
            String jwtString = jwt.serialize();
            System.out.println("\nJwt Compact Form : "+jwtString);

            // in order to read back the data from the token using your private RSA key:
            // parse the JWT text string using EncryptedJWT object
            jwt = EncryptedJWT.parse(jwtString);

            // create a decrypter with the specified private RSA key
            RSADecrypter decrypter = new RSADecrypter(privateRsaKey);

            // do the decryption
            jwt.decrypt(decrypter);

            // print out the claims

            System.out.println("===========================================================");
            System.out.println("Issuer: [ " + jwt.getJWTClaimsSet().getIssuer() + "]");
            System.out.println("Subject: [" + jwt.getJWTClaimsSet().getSubject()+ "]");
            System.out.println("Audience size: [" + jwt.getJWTClaimsSet().getAudience().size()+ "]");
            System.out.println("Expiration Time: [" + jwt.getJWTClaimsSet().getExpirationTime()+ "]");
            System.out.println("Not Before Time: [" + jwt.getJWTClaimsSet().getNotBeforeTime()+ "]");
            System.out.println("Issue At: [" + jwt.getJWTClaimsSet().getIssueTime()+ "]");
            System.out.println("JWT ID: [" + jwt.getJWTClaimsSet().getJWTID()+ "]");
            System.out.println("===========================================================");

        } catch (NoSuchAlgorithmException | InvalidKeySpecException | JOSEException | ParseException e) {
            System.out.println(e.getMessage());
        }
    }

    private static List<String> getAudience(){
        List<String> audience = new ArrayList<>();
        audience.add("https://my-web-app.com");
        audience.add("https://your-web-app.com");
        return audience;
    }
}

输出结果为:

声明集:

{"sub":"John Kerr","aud":["https:\/\/my-web-app.com","https:\/\/your-web-app.com"],"nbf":1471116052,"iss":"https:\/\/my-auth-server.com","exp":1471116652,"jti":"8769fc6d-b69f-45e3-b1a5-52695c23675e"}

Jwt紧凑格式:
eyJlbmMiOiJBMTI4R0NNIiwiYWxnIjoiUlNBLU9BRVAifQ.f2ZZyMaJi03RqunyWsLvIr7tNX1KvTRUcpN9qsBHvbXIouZCyepQMsbI1v88GHuLIV3f6SviCDyICp7kZCj_9q-yIi_dIuroADWQ-P_UnqNPRXQ1yEwbmrLUK80lBtKyc3Z6g_3Db_HLtD6QPEq-zUAh3wJ7uSPxhql2oc9otGc.Xbyrf4iWM0shNp4S.TCKoJGAEQ4rpJJk2qZP11awxTEWTg-r5VpppGgZNhiHCBhnGnyR2sb86O7ISc3j-i4OYp7Xl2vThzztD1ojy_IKPYQkg_iACuo6yjzdopQQT143vjYuFLfFhQFfjfCoO6iibTqK7vmqfF0bUWD6Nj-4MwjlW6dFV7mNQEN50dkiMrFMZkmiVKZRa50jOK1NcoWYiKSrCOQduJYibJfF6jSQARX9MsX5tib-3BXSsKtPLNrQ6mFfvDzzruBuO4gKWLE3PQPUfIQ.gXt5KcpxEbfYLP854GvcQw
===========================================================
Issuer: [ https://my-auth-server.com]
Subject: [John Kerr]
Audience size: [2]
Expiration Time: [Sun Aug 14 01:00:52 IST 2016]
Not Before Time: [Sun Aug 14 00:50:52 IST 2016]
Issue At: [null]
JWT ID: [8769fc6d-b69f-45e3-b1a5-52695c23675e]
===========================================================

1
//This is a complete encryption and decryption module using 
//Algorithm: JWEAlgorithm.RSA_OAEP_256
//Encryption Method: A128CBC_HS256

public static String  encrypt(String text) throws Exception {
    // Set the plain text
    Payload payload = new Payload(text);
    // Create the header
    JWEHeader header = new JWEHeader(JWEAlgorithm.RSA_OAEP_256, EncryptionMethod.A128CBC_HS256);
    // Create the JWE object and encrypt it
    JWEObject jweObject = new JWEObject(header, payload);
    jweObject.encrypt(new RSAEncrypter(getPublicKey()));
    // Serialise to compact JOSE form...
    String jweString = jweObject.serialize();
    LOG.info("Generated Encrypted Key : {}", jweString);
    return jweString;
}

public static String decrypt(String text) throws Exception {
    // Parse into JWE object...
    JWEObject jweObject = JWEObject.parse(text);
    jweObject.decrypt(new RSADecrypter(getPrivateKey()));
    // Get the plain text
    Payload payload = jweObject.getPayload();
    System.out.println(payload.toString());
    return payload.toString();
}

private static RSAPublicKey getPublicKey() throws Exception {
    String filename = "/home/vaibhav/Setups/cert/pub.der";
    File f = new File(filename);
    FileInputStream fis = new FileInputStream(f);
    DataInputStream dis = new DataInputStream(fis);
    byte[] keyBytes = new byte[(int)f.length()];
    dis.readFully(keyBytes);
    dis.close();

    X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    return (RSAPublicKey) kf.generatePublic(spec);
}

private static RSAPrivateKey getPrivateKey() throws Exception {
    String filename = "/home/vaibhav/Setups/cert/private.pkcs8";
    File f = new File(filename);
    FileInputStream fis = new FileInputStream(f);
    DataInputStream dis = new DataInputStream(fis);
    byte[] keyBytes = new byte[(int)f.length()];
    dis.readFully(keyBytes);
    dis.close();

    PKCS8EncodedKeySpec spec1 = new PKCS8EncodedKeySpec(keyBytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    return (RSAPrivateKey) kf.generatePrivate(spec1);
}

0

我实现了使用"nimbus-jose-jwt"库的代码,请在下面找到代码

JWTClaimsSet jwtClaims = new JWTClaimsSet();
jwtClaims.setIssuer(ISSUER);
jwtClaims.setSubject(SUBJECT);

List<String> aud = new ArrayList<String>();
aud.add("https://app-one.com");
aud.add("https://app-two.com");

jwtClaims.setAudience(aud);
// Set expiration in 10 minutes
jwtClaims.setExpirationTime(new Date(new Date().getTime() + 1000*60*10));
jwtClaims.setNotBeforeTime(new Date());
jwtClaims.setIssueTime(new Date());
jwtClaims.setJWTID(UUID.randomUUID().toString());

System.out.println("=========== JWT CLAMINS =============");
System.out.println(jwtClaims.toJSONObject());


// Request JWT encrypted with RSA-OAEP and 128-bit AES/GCM
JWEHeader header = new JWEHeader(JWEAlgorithm.RSA_OAEP, EncryptionMethod.A128GCM);

// Create the encrypted JWT object
EncryptedJWT jwt = new EncryptedJWT(header, jwtClaims);


// Create an encrypter with the specified public RSA key
RSAEncrypter encrypter = new RSAEncrypter(publicKey);
jwt.encrypt(encrypter);

String jwtString = jwt.serialize();

System.out.println(jwtString);


// Parse back
jwt = EncryptedJWT.parse(jwtString);

// Create a decrypter with the specified private RSA key
RSADecrypter decrypter = new RSADecrypter(privateKey);

// Decrypt
jwt.decrypt(decrypter);

// Retrieve JWT claims
System.out.println(jwt.getJWTClaimsSet().getIssuer());;
System.out.println(jwt.getJWTClaimsSet().getSubject());
System.out.println(jwt.getJWTClaimsSet().getAudience().size());
System.out.println(jwt.getJWTClaimsSet().getExpirationTime());
System.out.println(jwt.getJWTClaimsSet().getNotBeforeTime());
System.out.println(jwt.getJWTClaimsSet().getIssueTime());
System.out.println(jwt.getJWTClaimsSet().getJWTID());

这段代码还使用公钥和私钥来创建JWT令牌,您需要这些密钥来提取声明并验证它。
运行此代码后,您应该能够看到以下jwtClaims:
{
    "exp": 1429126207,
    "sub": "alice",
    "nbf": 1429125607,
    "aud": [
          "https://app-one.com",
          "https://app-two.com"
    ],
    "iss": "A FaceBook Cooperation",    
    "jti": "5c94d2db-e818-4746-b2f2-a4cd084d5a44",
    "iat": 1429125607
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接