@Override public JsonWebKey deriveKey(KeyParameters params, JsonWebKey jwk) throws CryptoException { if (params == null) { throw new IllegalArgumentException( "The 'params' argument may not be null for PBES2 Key derivation"); } Pbes2KeyParameters pbes2Params = Pbes2KeyParameters.cast(params); Pbes2Key derivedJwk = new Pbes2Key(); if (params.hasKeyId()) { derivedJwk.setKeyId(params.getKeyId()); } derivedJwk.setAlgorithm(String.format("PBES2-%s", pbes2Params.getAlgorithm().getHash())); derivedJwk.setKeyValue( deriveBits(CryptoParameters.cast(pbes2Params), jwk, pbes2Params.getKeyLength())); return derivedJwk; }
@Override public JsonWebKeySet createKeySet(KeyParameters params) throws CryptoException { if (params == null) { throw new IllegalArgumentException( "The 'params' argument may not be null for PBES2 Key generation"); } Pbes2KeyParameters pbes2Params = Pbes2KeyParameters.cast(params); Pbes2Key jwk = new Pbes2Key(); if (params.hasKeyId()) { jwk.setKeyId(params.getKeyId()); } if (params.hasAlgorithm()) { jwk.setAlgorithm(params.getAlgorithmString()); } if (pbes2Params.hasPasswordPolicy()) { jwk.put("pwd#policy", pbes2Params.getPasswordPolicy()); } return new JsonWebKeySet(jwk); }
@Override public byte[] deriveBits(CryptoParameters params, JsonWebKey jwk, int length) throws CryptoException { if (params == null) { throw new IllegalArgumentException( "The 'params' argument may not be null for PBES2 Key derivation"); } Pbes2KeyParameters pbes2Params = Pbes2KeyParameters.cast(params); Pbes2Key pbes2Jwk = (jwk != null ? Pbes2Key.cast(jwk) : new Pbes2Key()); if (length <= 0 || length % 8 != 0) { throw new IllegalArgumentException( String.format("length must be a positive multiple of 8 (%d%%8!=0)", length)); } String passwordPolicy = (pbes2Jwk.hasPasswordPolicy() ? pbes2Jwk.getPasswordPolicy() : null); String password; if (pbes2Params.hasPassword()) { password = pbes2Params.getPassword(); } else { if (onPasswordHandler_ == null) { throw new IllegalArgumentException("No OnPasswordHandler registered"); } password = onPasswordHandler_.onPassword( (pbes2Jwk.hasKeyId() ? pbes2Jwk.getKeyId() : null), passwordPolicy); if (password == null) { throw new CryptoException("Password request rejected"); } } if (!pbes2Params.hasSalt()) { pbes2Params.setSalt(Util.generateRandom(pbes2Params.getSaltLength())); } if (!pbes2Params.hasCount()) { // Make the default Count the official outbound value. pbes2Params.setCount(pbes2Params.getCount()); } PBEKeySpec keySpec = new PBEKeySpec( password.toCharArray(), pbes2Params.getSalt(), pbes2Params.getCount(), length); try { SecretKeyFactory keyFactory = getKeyFactoryForDigest(pbes2Params.getAlgorithm().getHash()); SecretKey key = keyFactory.generateSecret(keySpec); return key.getEncoded(); } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidKeySpecException | IllegalArgumentException e) { throw new CryptoException("Failed to derive bits", e); } }