package com.monkeyk.os.infrastructure;
import com.monkeyk.os.domain.shared.GuidGenerator;
import org.jose4j.jwe.ContentEncryptionAlgorithmIdentifiers;
import org.jose4j.jwe.JsonWebEncryption;
import org.jose4j.jwe.KeyManagementAlgorithmIdentifiers;
import org.jose4j.jwk.*;
import org.jose4j.jws.AlgorithmIdentifiers;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwt.JwtClaims;
import org.jose4j.jwt.consumer.JwtConsumer;
import org.jose4j.jwt.consumer.JwtConsumerBuilder;
import org.jose4j.keys.AesKey;
import org.jose4j.keys.EllipticCurves;
import org.testng.annotations.Test;
import java.security.Key;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNotNull;
/**
* 2016/12/15
*
* @author Shengzhao Li
*/
public class Jose4JTest {
/*
* AES 加密与解密, 128位
* */
@Test
public void aesEncryptDecrypt128() throws Exception {
String keyText = "iue98623diDEs096";
String data = "I am marico";
Key key = new AesKey(keyText.getBytes());
//加密
JsonWebEncryption jwe = new JsonWebEncryption();
jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.A128KW);
jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256);
jwe.setKey(key);
jwe.setPayload(data);
String idToken = jwe.getCompactSerialization();
assertNotNull(idToken);
System.out.println(data + " idToken: " + idToken);
//解密
JsonWebEncryption jwe2 = new JsonWebEncryption();
jwe2.setKey(key);
jwe2.setCompactSerialization(idToken);
final String payload = jwe2.getPayload();
assertNotNull(payload);
assertEquals(payload, data);
}
/*
* AES 加密与解密, 256位
* */
@Test
public void aesEncryptDecrypt256() throws Exception {
String keyText = "iue98623diDEs096_8u@idls(*JKse09";
String data = "I am marico";
Key key = new AesKey(keyText.getBytes());
//加密
JsonWebEncryption jwe = new JsonWebEncryption();
jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.A256KW);
jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_256_CBC_HMAC_SHA_512);
jwe.setKey(key);
jwe.setPayload(data);
String idToken = jwe.getCompactSerialization();
assertNotNull(idToken);
System.out.println(data + " idToken: " + idToken);
//解密
JsonWebEncryption jwe2 = new JsonWebEncryption();
jwe2.setKey(key);
jwe2.setCompactSerialization(idToken);
final String payload = jwe2.getPayload();
assertNotNull(payload);
assertEquals(payload, data);
}
/**
* JWT 生成 idToken, 并进行消费(consume)
* 算法:RSA SHA256
*
* @throws Exception
*/
@Test
public void jwtIdTokenConsumer() throws Exception {
String keyId = GuidGenerator.generate();
//生成idToken
JwtClaims claims = getJwtClaims();
JsonWebSignature jws = new JsonWebSignature();
jws.setPayload(claims.toJson());
jws.setKeyIdHeaderValue(keyId);
// Set the signature algorithm on the JWT/JWS that will integrity protect the claims
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.RSA_USING_SHA256);
RsaJsonWebKey jwk = RsaJwkGenerator.generateJwk(2048);
jwk.setKeyId(keyId);
//set private key
jws.setKey(jwk.getPrivateKey());
final String idToken = jws.getCompactSerialization();
assertNotNull(idToken);
System.out.println("idToken: " + idToken);
//解析idToken, 验签
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime() // the JWT must have an expiration time
.setMaxFutureValidityInMinutes(300) // but the expiration time can't be too crazy
.setAllowedClockSkewInSeconds(30) // allow some leeway in validating time based claims to account for clock skew
.setRequireSubject() // the JWT must have a subject claim
.setExpectedIssuer("Issuer") // whom the JWT needs to have been issued by
.setExpectedAudience("Audience") // to whom the JWT is intended for
//公钥
.setVerificationKey(jwk.getKey()) // verify the signature with the public key
.build(); // create the JwtConsumer instance
final JwtClaims jwtClaims = jwtConsumer.processToClaims(idToken);
assertNotNull(jwtClaims);
System.out.println(jwtClaims);
}
private JwtClaims getJwtClaims() {
JwtClaims claims = new JwtClaims();
claims.setIssuer("Issuer"); // who creates the token and signs it
claims.setAudience("Audience"); // to whom the token is intended to be sent
claims.setExpirationTimeMinutesInTheFuture(10); // time when the token will expire (10 minutes from now)
claims.setGeneratedJwtId(); // a unique identifier for the token
claims.setIssuedAtToNow(); // when the token was issued/created (now)
claims.setNotBeforeMinutesInThePast(2); // time before which the token is not yet valid (2 minutes ago)
claims.setSubject("subject"); // the subject/principal is whom the token is about
claims.setClaim("email", "mail@example.com"); // additional claims/attributes about the subject can be added
return claims;
}
/**
* JWT 生成 idToken+加密, 进行消费(consume)
* 使用EC
*
* @throws Exception
*/
@Test
public void jwtECIdTokenConsumer() throws Exception {
// String keyId = GuidGenerator.generate();
EllipticCurveJsonWebKey sendJwk = EcJwkGenerator.generateJwk(EllipticCurves.P256);
sendJwk.setKeyId(GuidGenerator.generate());
final String publicKeyString = sendJwk.toJson(JsonWebKey.OutputControlLevel.PUBLIC_ONLY);
final String privateKeyString = sendJwk.toJson(JsonWebKey.OutputControlLevel.INCLUDE_PRIVATE);
System.out.println("publicKeyString: " + publicKeyString);
System.out.println("privateKeyString: " + privateKeyString);
//生成 idToken
final JwtClaims jwtClaims = getJwtClaims();
JsonWebSignature jws = new JsonWebSignature();
jws.setPayload(jwtClaims.toJson());
//私钥
jws.setKey(sendJwk.getPrivateKey());
jws.setKeyIdHeaderValue(sendJwk.getKeyId());
jws.setAlgorithmHeaderValue(AlgorithmIdentifiers.ECDSA_USING_P256_CURVE_AND_SHA256);
String innerIdToken = jws.getCompactSerialization();
assertNotNull(innerIdToken);
System.out.println("innerIdToken: " + innerIdToken);
//对 idToken 进行加密
JsonWebEncryption jwe = new JsonWebEncryption();
jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.ECDH_ES_A128KW);
String encAlg = ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256;
jwe.setEncryptionMethodHeaderParameter(encAlg);
EllipticCurveJsonWebKey receiverJwk = EcJwkGenerator.generateJwk(EllipticCurves.P256);
receiverJwk.setKeyId(GuidGenerator.generate());
jwe.setKey(receiverJwk.getPublicKey());
jwe.setKeyIdHeaderValue(receiverJwk.getKeyId());
jwe.setContentTypeHeaderValue("JWT");
jwe.setPayload(innerIdToken);
String idToken = jwe.getCompactSerialization();
assertNotNull(idToken);
System.out.println("idToken: " + idToken);
//解析idToken, 验签
JwtConsumer jwtConsumer = new JwtConsumerBuilder()
.setRequireExpirationTime() // the JWT must have an expiration time
.setRequireSubject() // the JWT must have a subject claim
.setExpectedIssuer("Issuer") // whom the JWT needs to have been issued by
.setExpectedAudience("Audience") // to whom the JWT is intended for
//解密的私钥
.setDecryptionKey(receiverJwk.getPrivateKey()) // decrypt with the receiver's private key
//验签的公钥
.setVerificationKey(sendJwk.getPublicKey()) // verify the signature with the sender's public key
.build(); // create the JwtConsumer instance
final JwtClaims claims = jwtConsumer.processToClaims(idToken);
assertNotNull(claims);
System.out.println(claims);
}
}