JWSを作ってみたので、JWTも作ってみようと。
使用するライブラリは以前と同じです。
https://connect2id.com/products/nimbus-jose-jwt
作り方はこちらに載っていました。
https://connect2id.com/products/nimbus-jose-jwt/examples/jwt-with-hmac
実際に書いてみたコードはこちら。
import com.nimbusds.jose.JOSEException; import com.nimbusds.jose.JWSAlgorithm; import com.nimbusds.jose.JWSHeader; import com.nimbusds.jose.JWSVerifier; import com.nimbusds.jose.crypto.MACSigner; import com.nimbusds.jose.crypto.MACVerifier; import com.nimbusds.jwt.JWTClaimsSet; import com.nimbusds.jwt.SignedJWT; import java.security.SecureRandom; import java.text.ParseException; import java.util.Date; public class JWT_HS256 { public static void main(String[] args) throws JOSEException, ParseException { SecureRandom secureRandom = new SecureRandom(); byte[] sharedSecret = new byte[32]; secureRandom.nextBytes(sharedSecret); // HMACの署名を行うクラスの作成 MACSigner signer = new MACSigner(sharedSecret); // JWTクレーム・セットの作成 JWTClaimsSet claimsSet = new JWTClaimsSet.Builder() .subject("alice") .issuer("https://fogefoge.com") .expirationTime(new Date(new Date().getTime() + 60 * 1000)) .build(); // JWSヘッダーとJWTクレームセットを合わせ、署名を行い、JWTを作成 SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256), claimsSet); signedJWT.sign(signer); String s = signedJWT.serialize(); System.out.println("Created jwt: " + s); // JWTをデシリアライズ SignedJWT parsedSignedJWT = SignedJWT.parse(s); // JWTの署名を検証 JWSVerifier verifier = new MACVerifier(sharedSecret); System.out.println("Verify mac: " + parsedSignedJWT.verify(verifier)); // JWTのクレームを取得 System.out.println(parsedSignedJWT.getJWTClaimsSet().getSubject()); System.out.println(parsedSignedJWT.getJWTClaimsSet().getIssuer()); System.out.println(parsedSignedJWT.getJWTClaimsSet().getExpirationTime()); } }
JWSとJWTのRFCを軽く読んだだけですが、各メソッドやクラスが正しくRFCの内容と一致しているかなと思います。JWSヘッダーがあり、クレームセットがあって、JWTが作られるあたりとか特に。
ちなみにJWTを署名処理しないでシリアライズしようとすると例外が出て怒られます。
SignedJWT signedJWT = new SignedJWT(new JWSHeader(JWSAlgorithm.HS256), claimsSet); System.out.println("Before sign jwt: " + signedJWT.serialize());
Exception in thread "main" java.lang.IllegalStateException: The JWS object must be in a signed or verified state at com.nimbusds.jose.JWSObject.ensureSignedOrVerifiedState(JWSObject.java:264) at com.nimbusds.jose.JWSObject.serialize(JWSObject.java:420) at com.nimbusds.jose.JWSObject.serialize(JWSObject.java:399) at JWT_HS256.main(JWT_HS256.java:32)