private Map<String, Object> createRSAJWK(RSAPublicKey key, KeyUse use, String alg) throws ServerException { String alias = null; try { alias = getStringSetting(realm, OAuth2Constants.OAuth2ProviderService.KEYSTORE_ALIAS); } catch (SSOException | SMSException e) { logger.error(e.getMessage()); throw new ServerException(e); } if (StringUtils.isBlank(alias)) { logger.error("Alias of ID Token Signing Key not set."); throw new ServerException("Alias of ID Token Signing Key not set."); } else if ("test".equals(alias)) { logger.warning("Alias of ID Token Signing Key should be changed from default, 'test'."); } String kid = Hash.hash(alias + key.getModulus().toString() + key.getPublicExponent().toString()); return json(object( field("kty", "RSA"), field(OAuth2Constants.JWTTokenParams.KEY_ID, kid), field("use", use.toString()), field("alg", alg), field("n", Base64url.encode(key.getModulus().toByteArray())), field("e", Base64url.encode(key.getPublicExponent().toByteArray())))) .asMap(); }
/** * Generates hash values, by hashing the valueToEncode using the requests's "alg" parameter, then * returning the base64url encoding of the leftmost half of the returned bytes. Used for both * at_hash and c_hash claims. */ private String generateHash( String algorithm, String valueToEncode, OAuth2ProviderSettings providerSettings) throws ServerException { if (!providerSettings.getSupportedIDTokenSigningAlgorithms().contains(algorithm)) { logger.message("Unsupported signing algorithm requested for hash value."); return null; } final JwsAlgorithm alg = JwsAlgorithm.valueOf(algorithm); MessageDigest digest; try { digest = MessageDigest.getInstance(alg.getMdAlgorithm()); } catch (NoSuchAlgorithmException e) { logger.message("Unsupported signing algorithm chosen for hashing."); throw new ServerException("Algorithm not supported."); } final byte[] result = digest.digest(valueToEncode.getBytes(Utils.CHARSET)); final byte[] toEncode = Arrays.copyOfRange(result, 0, result.length / 2); return Base64url.encode(toEncode); }