@Override public JWTSigningAndValidationService load(String key) throws Exception { try { String id = "SYMMETRIC-KEY"; JWK jwk = new OctetSequenceKey.Builder(Base64URL.encode(key)) .keyUse(KeyUse.SIGNATURE) .keyID(id) .build(); Map<String, JWK> keys = ImmutableMap.of(id, jwk); JWTSigningAndValidationService service = new DefaultJWTSigningAndValidationService(keys); return service; } catch (NoSuchAlgorithmException | InvalidKeySpecException e) { logger.error("Couldn't create symmetric validator for client", e); } throw new IllegalArgumentException("Couldn't create symmetric validator for client"); }
public static Base64URL getHash(JWSAlgorithm signingAlg, byte[] bytes) { //Switch based on the given signing algorithm - use SHA-xxx with the same 'xxx' bitnumber //as the JWSAlgorithm to hash the token. String hashAlg = null; if (signingAlg.equals(JWSAlgorithm.HS256) || signingAlg.equals(JWSAlgorithm.ES256) || signingAlg.equals(JWSAlgorithm.RS256) || signingAlg.equals(JWSAlgorithm.PS256)) { hashAlg = "SHA-256"; } else if (signingAlg.equals(JWSAlgorithm.ES384) || signingAlg.equals(JWSAlgorithm.HS384) || signingAlg.equals(JWSAlgorithm.RS384) || signingAlg.equals(JWSAlgorithm.PS384)) { hashAlg = "SHA-384"; } else if (signingAlg.equals(JWSAlgorithm.ES512) || signingAlg.equals(JWSAlgorithm.HS512) || signingAlg.equals(JWSAlgorithm.RS512) || signingAlg.equals(JWSAlgorithm.PS512)) { hashAlg = "SHA-512"; } if (hashAlg != null) { try { MessageDigest hasher = MessageDigest.getInstance(hashAlg); hasher.reset(); hasher.update(bytes); byte[] hashBytes = hasher.digest(); byte[] hashBytesLeftHalf = Arrays.copyOf(hashBytes, hashBytes.length / 2); Base64URL encodedHash = Base64URL.encode(hashBytesLeftHalf); return encodedHash; } catch (NoSuchAlgorithmException e) { logger.error("No such algorithm error: ", e); } } return null; }
try { MessageDigest digest = MessageDigest.getInstance("SHA-256"); String hash = Base64URL.encode(digest.digest(codeVerifier.getBytes(StandardCharsets.US_ASCII))).toString(); options.put("code_challenge", hash); } catch (NoSuchAlgorithmException e) {
String hash = Base64URL.encode(digest.digest(verifier.getBytes(StandardCharsets.US_ASCII))).toString(); if (!challenge.equals(hash)) { throw new InvalidRequestException("Code challenge and verifier do not match");
/** * Creates a new octet sequence JWK builder. * * @param key The key value. Must not be empty byte array or * {@code null}. */ public Builder(final byte[] key) { this(Base64URL.encode(key)); if (key.length == 0) { throw new IllegalArgumentException("The key must have a positive length"); } }
/** * Base64URL-encodes the specified string. * * @param text The string to encode. Must be in the UTF-8 character set * and not {@code null}. * * @return The resulting Base64URL object. */ public static Base64URL encode(final String text) { return encode(text.getBytes(StandardCharset.UTF_8)); } }
/** * Computes the X.509 certificate SHA-256 thumbprint ({@code x5t#S256}). * * @param cert The X.509 certificate. Must not be {@code null}. * * @return The SHA-256 thumbprint, BASE64URL-encoded, {@code null} if * a certificate encoding exception is encountered. */ public static Base64URL computeSHA256Thumbprint(final X509Certificate cert) { try { byte[] derEncodedCert = cert.getEncoded(); MessageDigest sha256 = MessageDigest.getInstance("SHA-256"); return Base64URL.encode(sha256.digest(derEncodedCert)); } catch (NoSuchAlgorithmException | CertificateEncodingException e) { return null; } } }
/** * Returns a Base64URL representation of this payload. * * @return The Base64URL representation. */ public Base64URL toBase64URL() { if (base64URL != null) { return base64URL; } // Convert return Base64URL.encode(toBytes()); }
/** * Creates a new JWK Other Primes Info from the specified * {@code java.security.spec.RSAOtherPrimeInfo} instance. * * @param oth The RSA Other Primes Info instance. Must not be * {@code null}. */ public OtherPrimesInfo(final RSAOtherPrimeInfo oth) { r = Base64URL.encode(oth.getPrime()); d = Base64URL.encode(oth.getExponent()); t = Base64URL.encode(oth.getCrtCoefficient()); }
/** * Base64URL-encodes the specified big integer, without the sign bit. * * @param bigInt The big integer to encode. Must not be {@code null}. * * @return The resulting Base64URL object. */ public static Base64URL encode(final BigInteger bigInt) { return encode(BigIntegerUtils.toBytesUnsigned(bigInt)); }
/** * Returns a Base64URL representation of the header. If the header was * parsed always returns the original Base64URL (required for JWS * validation and authenticated JWE decryption). * * @return The original parsed Base64URL representation of the header, * or a new Base64URL representation if the header was created * from scratch. */ public Base64URL toBase64URL() { if (parsedBase64URL == null) { // Header was created from scratch, return new Base64URL return Base64URL.encode(toString()); } else { // Header was parsed, return original Base64URL return parsedBase64URL; } }
/** * Sets the private RSA key, using the second representation * (see RFC 3447, section 3.2). * * @param priv The private RSA key, used to obtain the private * exponent ({@code d}), the first prime factor * ({@code p}), the second prime factor * ({@code q}), the first factor CRT exponent * ({@code dp}), the second factor CRT exponent * ({@code dq}) and the first CRT coefficient * ({@code qi}). Must not be {@code null}. * * @return This builder. */ public Builder privateKey(final RSAPrivateCrtKey priv) { d = Base64URL.encode(priv.getPrivateExponent()); p = Base64URL.encode(priv.getPrimeP()); q = Base64URL.encode(priv.getPrimeQ()); dp = Base64URL.encode(priv.getPrimeExponentP()); dq = Base64URL.encode(priv.getPrimeExponentQ()); qi = Base64URL.encode(priv.getCrtCoefficient()); return this; }
/** * Sets the private RSA key, using the first representation. * * @param priv The private RSA key, used to obtain the private * exponent ({@code d}). Must not be {@code null}. * * @return This builder. */ public Builder privateKey(final RSAPrivateKey priv) { if (priv instanceof RSAPrivateCrtKey) { return this.privateKey((RSAPrivateCrtKey) priv); } else if (priv instanceof RSAMultiPrimePrivateCrtKey) { return this.privateKey((RSAMultiPrimePrivateCrtKey) priv); } else { this.d = Base64URL.encode(priv.getPrivateExponent()); return this; } }
/** * @param keySize in bits * @return */ public static OctetSequenceKey make(Integer keySize, KeyUse use, Algorithm alg, String kid) { // holder for the random bytes byte[] bytes = new byte[keySize / 8]; // make a random number generator and fill our holder SecureRandom sr = new SecureRandom(); sr.nextBytes(bytes); Base64URL encoded = Base64URL.encode(bytes); // make a key OctetSequenceKey octetSequenceKey = new OctetSequenceKey.Builder(encoded) .keyID(kid) .algorithm(alg) .keyUse(use) .build(); return octetSequenceKey; }
@Override public Base64URL sign(final JWSHeader header, final byte[] signingInput) throws JOSEException { Signature signer = RSASSA.getSignerAndVerifier(header.getAlgorithm(), getJCAContext().getProvider()); try { signer.initSign(privateKey); signer.update(signingInput); return Base64URL.encode(signer.sign()); } catch (InvalidKeyException e) { throw new JOSEException("Invalid private RSA key: " + e.getMessage(), e); } catch (SignatureException e) { throw new JOSEException("RSA signature exception: " + e.getMessage(), e); } } }
@Override public Base64URL sign(final JWSHeader header, final byte[] signingInput) throws JOSEException { // Check alg field in header final JWSAlgorithm alg = header.getAlgorithm(); if (! JWSAlgorithm.EdDSA.equals(alg)) { throw new JOSEException("Ed25519Signer requires alg=EdDSA in JWSHeader"); } final byte[] jwsSignature; try { jwsSignature = tinkSigner.sign(signingInput); } catch (GeneralSecurityException e) { throw new JOSEException(e.getMessage(), e); } return Base64URL.encode(jwsSignature); } }
public String sign(final boolean internalOnly, final JWTClaimsSet claimsSet, final ActivableAndExpirable internalKey, final ActivableAndExpirable externalKey, final boolean isRefreshToken) { final ProfileOAuth2 profile = this.profile.getProfile(); final String inner = super.signJWT(new Payload(claimsSet.toJSONObject()), profile.getInternalKeyAlgorithm(), internalKey, isRefreshToken, Jwt.CTY.DEFAULT.getValue()); // no need to wrap if both keys are equals - this is the case for internal clients who are going to set both to internal key // obviously the JWT algorithm will reject the token if it is used to get in as the internal key isn't in the permitted keys if (internalOnly || externalKey == null || internalKey.equals(externalKey)) { LOGGER.fine(Oauth2Codes.PLAIN_INNER_TOKEN_2, "Return plain inner token with JTI {0}, internal-key={1}, external-key={2}", claimsSet.getJWTID(), internalKey, externalKey); return inner; } return super.signJWT(new Payload(Base64URL.encode(inner)), profile.getExternalKeyAlgorithm(), externalKey, isRefreshToken, Jwt.CTY.WRAPPED.getValue()); } }
@Override public JWECryptoParts encrypt(final JWEHeader header, final byte[] clearText) throws JOSEException { final JWEAlgorithm alg = header.getAlgorithm(); final EncryptionMethod enc = header.getEncryptionMethod(); final byte[] salt = new byte[saltLength]; getJCAContext().getSecureRandom().nextBytes(salt); final byte[] formattedSalt = PBKDF2.formatSalt(alg, salt); final PRFParams prfParams = PRFParams.resolve(alg, getJCAContext().getMACProvider()); final SecretKey psKey = PBKDF2.deriveKey(getPassword(), formattedSalt, iterationCount, prfParams); // We need to work on the header final JWEHeader updatedHeader = new JWEHeader.Builder(header). pbes2Salt(Base64URL.encode(salt)). pbes2Count(iterationCount). build(); final SecretKey cek = ContentCryptoProvider.generateCEK(enc, getJCAContext().getSecureRandom()); // The second JWE part final Base64URL encryptedKey = Base64URL.encode(AESKW.wrapCEK(cek, psKey, getJCAContext().getKeyEncryptionProvider())); return ContentCryptoProvider.encrypt(updatedHeader, clearText, cek, encryptedKey, getJCAContext()); }
@Override public Base64URL sign(final JWSHeader header, final byte[] signingInput) throws JOSEException { final int minRequiredLength = getMinRequiredSecretLength(header.getAlgorithm()); if (getSecret().length < ByteUtils.byteLength(minRequiredLength)) { throw new KeyLengthException("The secret length for " + header.getAlgorithm() + " must be at least " + minRequiredLength + " bits"); } String jcaAlg = getJCAAlgorithmName(header.getAlgorithm()); byte[] hmac = HMAC.compute(jcaAlg, getSecret(), signingInput, getJCAContext().getProvider()); return Base64URL.encode(hmac); } }