protected RecipientOperator getRecipientOperator(Recipient recipient) throws CMSException, IOException { PasswordRecipient pbeRecipient = (PasswordRecipient)recipient; AlgorithmIdentifier kekAlg = AlgorithmIdentifier.getInstance(info.getKeyEncryptionAlgorithm()); AlgorithmIdentifier kekAlgParams = AlgorithmIdentifier.getInstance(kekAlg.getParameters()); byte[] passwordBytes = getPasswordBytes(pbeRecipient.getPasswordConversionScheme(), pbeRecipient.getPassword()); PBKDF2Params params = PBKDF2Params.getInstance(info.getKeyDerivationAlgorithm().getParameters()); PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(); gen.init(passwordBytes, params.getSalt(), params.getIterationCount().intValue()); int keySize = ((Integer)KEYSIZES.get(kekAlgParams.getAlgorithm())).intValue(); byte[] derivedKey = ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey(); return pbeRecipient.getRecipientOperator(kekAlgParams, messageAlgorithm, derivedKey, info.getEncryptedKey().getOctets()); }
@Test public void compareModes() { BlockCipher engine = new AESEngine(); int blockSize = engine.getBlockSize(); BlockCipher ref = new SICBlockCipher(engine); // reference implementation BlockCipher uut = new CtrBlockCipher(engine); // unit under test PBEParametersGenerator gen = new PKCS5S2ParametersGenerator(); byte[] salt = new byte[blockSize]; // used as salt and cipher input new SecureRandom().nextBytes(salt); gen.init("top secret".getBytes(), salt, 1); ParametersWithIV param = (ParametersWithIV) gen.generateDerivedParameters( blockSize * 8, blockSize * 8); ref.init(true, param); uut.init(true, param); assertModes(ref, uut); ref.init(false, param); uut.init(false, param); assertModes(ref, uut); }
private void internalSetUserPassword(SUser user, String newPassword) throws TException { BouncyCastleUtil.ensureInitialized(); byte[] newSalt = new byte[SALT_LENGTH_BYTES]; if (useStrongRandom) { try { SecureRandom.getInstanceStrong().nextBytes(newSalt); } catch (NoSuchAlgorithmException e) { logger.error("Internal error when calculating new salt for new password", e); throw new TException("Internal error.", e); } } else { // use non-string random. ThreadLocalRandom.current().nextBytes(newSalt); } PKCS5S2ParametersGenerator pbkdf2sha256 = new PKCS5S2ParametersGenerator(new SHA256Digest()); pbkdf2sha256.init(newPassword.getBytes(Charset.forName("UTF-8")), newSalt, PBKDF2_ITERATIONS); byte[] newHash = ((KeyParameter) pbkdf2sha256.generateDerivedParameters(HASH_LENGTH_BYTES * 8)).getKey(); user.setPassword(new SPassword()); user.getPassword().setHash(newHash); user.getPassword().setSalt(newSalt); }
byte[] getEncoded(String algorithmOid) { PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(); gen.init(PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(this.getPassword()), this.getSalt(), this.getIterationCount()); return ((KeyParameter)gen.generateDerivedParameters(CMSEnvelopedHelper.INSTANCE.getKeySize(algorithmOid))).getKey(); }
byte[] getEncoded(String algorithmOid) { PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(); gen.init(PBEParametersGenerator.PKCS5PasswordToBytes(this.getPassword()), this.getSalt(), this.getIterationCount()); return ((KeyParameter)gen.generateDerivedParameters(CMSEnvelopedHelper.INSTANCE.getKeySize(algorithmOid))).getKey(); }
public static SecretKey generateSecretKeyForPKCS5Scheme2(String algorithm, char[] password, byte[] salt, int iterationCount) { PBEParametersGenerator generator = new PKCS5S2ParametersGenerator(); generator.init( PBEParametersGenerator.PKCS5PasswordToBytes(password), salt, iterationCount); return new SecretKeySpec(((KeyParameter)generator.generateDerivedParameters(PEMUtilities.getKeySize(algorithm))).getKey(), algorithm); }
private static byte[] generateAes128CtrDerivedKey( byte[] password, byte[] salt, int c, String prf) throws CipherException { if (!prf.equals("hmac-sha256")) { throw new CipherException("Unsupported prf:" + prf); } // Java 8 supports this, but you have to convert the password to a character array, see // http://stackoverflow.com/a/27928435/3211687 PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest()); gen.init(password, salt, c); return ((KeyParameter) gen.generateDerivedParameters(256)).getKey(); }
protected byte[] calculateDerivedKey(int schemeID, AlgorithmIdentifier derivationAlgorithm, int keySize) throws CMSException { PBKDF2Params params = PBKDF2Params.getInstance(derivationAlgorithm.getParameters()); byte[] encodedPassword = (schemeID == PasswordRecipient.PKCS5_SCHEME2) ? PBEParametersGenerator.PKCS5PasswordToBytes(password) : PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password); PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(); gen.init(encodedPassword, params.getSalt(), params.getIterationCount().intValue()); return ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey(); }
public byte[] calculateDerivedKey(int schemeID, AlgorithmIdentifier derivationAlgorithm, int keySize) throws CMSException { PBKDF2Params params = PBKDF2Params.getInstance(derivationAlgorithm.getParameters()); byte[] encodedPassword = (schemeID == PasswordRecipient.PKCS5_SCHEME2) ? PBEParametersGenerator.PKCS5PasswordToBytes(password) : PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(password); PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(); gen.init(encodedPassword, params.getSalt(), params.getIterationCount().intValue()); return ((KeyParameter)gen.generateDerivedParameters(keySize)).getKey(); }
/** * Encrypt and encrypt the plain text. * * @param secret Password to be encrypted. * @param cipherKey Password use for encryption. * @return Encrypted value. * @throws Exception If an error occurred while encrypting. */ private static String encrypt(String secret, char[] cipherKey) throws EncryptingException { try { // Change char array to byte array. ByteBuffer buf = StandardCharsets.UTF_8.encode(CharBuffer.wrap(cipherKey)); byte[] secretKey = new byte[buf.limit()]; buf.get(secretKey); PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest()); gen.init(secretKey, SALT.getBytes(), KEY_DERIVATION_ITERATION_COUNT); byte[] key = ((KeyParameter) gen.generateDerivedParameters(KEY_SIZE)).getKey(); SecretKey secretKeySpec = new SecretKeySpec(key, "AES"); Cipher cipher = Cipher.getInstance(ALGORITHM); // Create an initialization vector with Cipher's block size. byte[] iv = new byte[cipher.getBlockSize()]; IvParameterSpec ivParams = new IvParameterSpec(iv); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParams); // Encrypt the password. byte[] encryptedVal = cipher.doFinal(secret.getBytes(StandardCharsets.UTF_8)); // Encode the password. byte[] encodedVal = new Base64().encode(encryptedVal); return new String(encodedVal, StandardCharsets.UTF_8); } catch (NoSuchAlgorithmException | InvalidKeyException | InvalidAlgorithmParameterException | NoSuchPaddingException | BadPaddingException | IllegalBlockSizeException ex) { throw new EncryptingException("Error while encrypting", ex); } }
/** * Decrypt and decrypt the encrypted values. * * @param encryptedSecret encrypted value. * @param cipherKey password used for encryption. * @return * @throws SSOAgentException If an error occurred. */ public static String decrypt(String encryptedSecret, char[] cipherKey) throws SSOAgentException { try { // Change char array to byte array. ByteBuffer buf = StandardCharsets.UTF_8.encode(CharBuffer.wrap(cipherKey)); byte[] secretKey = new byte[buf.limit()]; buf.get(secretKey); PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest()); gen.init(secretKey, SALT.getBytes(StandardCharsets.UTF_8), KEY_DERIVATION_ITERATION_COUNT); byte[] dk = ((KeyParameter) gen.generateDerivedParameters(KEY_SIZE)).getKey(); SecretKey key = new SecretKeySpec(dk, "AES"); Cipher cipher = Cipher.getInstance(ALGORITHM); // Create an initialization vector with Cipher's block size. byte[] iv = new byte[cipher.getBlockSize()]; IvParameterSpec ivParams = new IvParameterSpec(iv); cipher.init(Cipher.DECRYPT_MODE, key, ivParams); // Decode the encrypted value. byte[] decodedValue = new Base64().decode(encryptedSecret.getBytes(StandardCharsets.UTF_8)); // Decrypt the encrypted value and get the plain text password. byte[] decryptedValue = cipher.doFinal(decodedValue); return new String(decryptedValue, StandardCharsets.UTF_8); } catch (Exception ex) { throw new SSOAgentException("Error while decoding the encrypted value.", ex); } }
public static KeyParameter generateSecretKeyForPKCS5Scheme2(String algorithm, char[] password, byte[] salt, int iterationCount) { PBEParametersGenerator paramsGen = new PKCS5S2ParametersGenerator(new SHA1Digest()); paramsGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), salt, iterationCount); return (KeyParameter)paramsGen.generateDerivedParameters(PEMUtilities.getKeySize(algorithm)); }
@Override public Inventory readInventoryFromBytes(byte[] source, UserSecurityProvider usp) throws BaseBunkrException { try { if (this.encryptionAlgorithm == Encryption.NONE) throw new IllegalArgumentException("PBKDF2Descriptor requires an active encryption mode"); PKCS5S2ParametersGenerator g = new PKCS5S2ParametersGenerator(new SHA256Digest()); g.init(usp.getHashedPassword(), this.pbkdf2Salt, this.pbkdf2Iterations); ParametersWithIV kp = (ParametersWithIV) g.generateDerivedParameters( this.encryptionAlgorithm.keyByteLength * 8, this.encryptionAlgorithm.ivByteLength * 8); byte[] decryptedInv = SimpleBlockCipher.decrypt( this.encryptionAlgorithm, source, ((KeyParameter) kp.getParameters()).getKey(), kp.getIV() ); return InventoryJSON.decode(new String(decryptedInv)); } catch (IllegalPasswordException | CryptoException e) { throw new BaseBunkrException(e); } }
@Override public byte[] writeInventoryToBytes(Inventory source, UserSecurityProvider usp) throws BaseBunkrException { try { byte[] inventoryJsonBytes = InventoryJSON.encode(source).getBytes(); if (this.encryptionAlgorithm == Encryption.NONE) throw new IllegalArgumentException("PBKDF2Descriptor requires an active encryption mode"); // first refresh the salt RandomMaker.fill(this.pbkdf2Salt); PKCS5S2ParametersGenerator g = new PKCS5S2ParametersGenerator(new SHA256Digest()); g.init(usp.getHashedPassword(), this.pbkdf2Salt, this.pbkdf2Iterations); ParametersWithIV kp = (ParametersWithIV) g.generateDerivedParameters( this.encryptionAlgorithm.keyByteLength * 8, this.encryptionAlgorithm.ivByteLength * 8); // encrypt the inventory byte[] encryptedInv = SimpleBlockCipher.encrypt( this.encryptionAlgorithm, inventoryJsonBytes, ((KeyParameter) kp.getParameters()).getKey(), kp.getIV() ); Arrays.fill(inventoryJsonBytes, (byte) 0); return encryptedInv; } catch (IllegalPasswordException | CryptoException e) { throw new BaseBunkrException(e); } }
private static byte[] deriveKey(char[] password, byte[] salt) throws UnsupportedEncodingException { // generate key using PBKDF2 PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA512Digest()); gen.init(new String(password).getBytes("UTF-8"), salt, PBKDF2_ITERATIONS); return ((KeyParameter) gen.generateDerivedParameters(AES_KEY_SIZE_BITS)).getKey(); }
@Test public void testPBKDF() throws Exception { Security.addProvider(new BouncyCastleProvider()); Random r = new Random(); char[] cPassword = "ThePa55wordToU5e".toCharArray(); byte[] salt = new byte[64]; r.nextBytes(salt); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); KeySpec keyspec = new PBEKeySpec(cPassword, salt, 5000, 256); Key key = factory.generateSecret(keyspec); byte[] k1 = key.getEncoded(); factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1", "BC"); key = factory.generateSecret(keyspec); byte[] k2 = key.getEncoded(); assertArrayEquals(k1, k2); PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA1Digest()); gen.init(new String(cPassword).getBytes("UTF-8"), salt, 5000); byte[] k3 = ((KeyParameter) gen.generateDerivedParameters(256)).getKey(); assertArrayEquals(k1, k3); assertArrayEquals(k2, k3); }
public void init( String pwStr, int keySize, byte[] salt, byte[] pwVerification ) throws ZipException { byte[] pwBytes = pwStr.getBytes(); super.saltBytes = salt; PBEParametersGenerator generator = new PKCS5S2ParametersGenerator(); generator.init( pwBytes, salt, ITERATION_COUNT ); cipherParameters = generator.generateDerivedParameters(KEY_SIZE_BIT*2 + 16); byte[] keyBytes = ((KeyParameter)cipherParameters).getKey(); this.cryptoKeyBytes = new byte[ KEY_SIZE_BYTE ]; System.arraycopy( keyBytes, 0, cryptoKeyBytes, 0, KEY_SIZE_BYTE ); this.authenticationCodeBytes = new byte[ KEY_SIZE_BYTE ]; System.arraycopy( keyBytes, KEY_SIZE_BYTE, authenticationCodeBytes, 0, KEY_SIZE_BYTE ); // based on SALT + PASSWORD (password is probably correct) this.pwVerificationBytes = new byte[ 2 ]; System.arraycopy( keyBytes, KEY_SIZE_BYTE*2, this.pwVerificationBytes, 0, 2 ); if( !ByteArrayHelper.isEqual( this.pwVerificationBytes, pwVerification ) ) { throw new ZipException("wrong password - " + ByteArrayHelper.toString(this.pwVerificationBytes) + "/ " + ByteArrayHelper.toString(pwVerification)); } // create the first 16 bytes of the key sequence again (using pw+salt) generator.init( pwBytes, salt, ITERATION_COUNT ); cipherParameters = generator.generateDerivedParameters(KEY_SIZE_BIT); // checksum added to the end of the encrypted data, update on each encryption call this.mac = new HMac( new SHA1Digest() ); mac.init( new KeyParameter(authenticationCodeBytes) ); this.aesCipher = new SICBlockCipher(new AESEngine()); this.blockSize = aesCipher.getBlockSize(); // incremented on each 16 byte block and used as encryption NONCE (ivBytes) nonce = 1; }
public static byte[] wrapKey(byte[] secretKey, String password) { byte[] tempsalt = "TEST".getBytes(); PBEParametersGenerator generator = new PKCS5S2ParametersGenerator(); generator.init(PBEParametersGenerator.PKCS5PasswordToBytes(password.toCharArray()), tempsalt, 5); //Technically we probably shouldn't need a CTS cipher here, but it's fine to be consistent BufferedBlockCipher cipher = CryptUtil.getAesCtsCipher(); cipher.init(true, generator.generateDerivedParameters(PBE_KEY_SIZE)); byte[] wrapped = encrypt(secretKey, cipher); return wrapped; }
public static byte[] unWrapKey(byte[] wrapped, String password) { byte[] tempsalt = "TEST".getBytes(); PBEParametersGenerator generator = new PKCS5S2ParametersGenerator(); generator.init(PBEParametersGenerator.PKCS5PasswordToBytes(password.toCharArray()), tempsalt, 5); //Technically we probably shouldn't need a CTS cipher here, but it's fine to be consistent BufferedBlockCipher cipher = CryptUtil.getAesCtsCipher(); cipher.init(false, generator.generateDerivedParameters(PBE_KEY_SIZE)); byte[] unWrapped = decrypt(wrapped, cipher); return unWrapped; }
@Override public ByteArray newKey(DerivedKeyParams keyParams) throws EncryptionException { PBEParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA1Digest()); gen.init(keyParams.getPassword(), keyParams.getSalt(), keyParams.getIterations()); KeyParameter keyParam = (KeyParameter) gen.generateDerivedParameters(keyParams.getKeySize()); return new ByteArray(keyParam.getKey()); }
public String encode(String password, byte[] salt, int rounds) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeySpecException { PKCS5S2ParametersGenerator generator = new PKCS5S2ParametersGenerator(); generator.init(PBEParametersGenerator.PKCS5PasswordToBytes( password.toCharArray()), salt, rounds); return format("%s:%s:%d", encode(salt), encode(((KeyParameter)generator.generateDerivedParameters(s_keylen)).getKey()), rounds); }
public static void main( String[] args) { HMac gMac = new HMac(new GOST3411Digest(GOST28147Engine.getSBox("D-Test"))); gMac.init(new KeyParameter(PKCS5S1ParametersGenerator.PKCS5PasswordToUTF8Bytes("Boss".toCharArray()))); byte[] iBuf = new byte[4]; byte[] data = Hex.decode("b5d78fa546ba645c"); gMac.update(data, 0, data.length); byte[] mac = new byte[gMac.getMacSize()]; int pos = 3; while (++iBuf[pos] == 0) { --pos; } gMac.update(iBuf, 0, iBuf.length); gMac.doFinal(mac, 0); System.err.println(mac.length + " " + new String(Hex.encode(mac))); PKCS5S2ParametersGenerator pGen = new PKCS5S2ParametersGenerator(new GOST3411Digest()); pGen.init(PKCS5S1ParametersGenerator.PKCS5PasswordToUTF8Bytes("1".toCharArray()), data, 2048); KeyParameter kp = (KeyParameter)pGen.generateDerivedMacParameters(256); System.err.println(kp.getKey().length + " " + new String(Hex.encode(kp.getKey()))); runTest(new GOST3411DigestTest()); }
/** * Setup AES encryption based on pwBytes using WinZipAES approach * with SALT and pwVerification bytes based on password+salt. */ public void init( String pwStr, int keySize ) throws ZipException { byte[] pwBytes = pwStr.getBytes(); PBEParametersGenerator generator = new PKCS5S2ParametersGenerator(); this.saltBytes = createSalt(); generator.init( pwBytes, saltBytes, ITERATION_COUNT ); // create 2 byte[16] for two keys and one byte[2] for pwVerification // 1. encryption / 2. athentication (via HMAC/hash) / cipherParameters = generator.generateDerivedParameters(KEY_SIZE_BIT*2 + 16); byte[] keyBytes = ((KeyParameter)cipherParameters).getKey(); this.cryptoKeyBytes = new byte[ KEY_SIZE_BYTE ]; System.arraycopy( keyBytes, 0, cryptoKeyBytes, 0, KEY_SIZE_BYTE ); this.authenticationCodeBytes = new byte[ KEY_SIZE_BYTE ]; System.arraycopy( keyBytes, KEY_SIZE_BYTE, authenticationCodeBytes, 0, KEY_SIZE_BYTE ); // based on SALT + PASSWORD (password is probably correct) this.pwVerificationBytes = new byte[ 2 ]; System.arraycopy( keyBytes, KEY_SIZE_BYTE*2, pwVerificationBytes, 0, 2 ); // create the first 16 bytes of the key sequence again (using pw+salt) generator.init( pwBytes, saltBytes, ITERATION_COUNT ); cipherParameters = generator.generateDerivedParameters(KEY_SIZE_BIT); // checksum added to the end of the encrypted data, update on each encryption call this.mac = new HMac( new SHA1Digest() ); mac.init( new KeyParameter(authenticationCodeBytes) ); this.aesCipher = new SICBlockCipher(new AESEngine()); this.blockSize = aesCipher.getBlockSize(); // incremented on each 16 byte block and used as encryption NONCE (ivBytes) nonce = 1; if( LOG.isLoggable(Level.FINEST) ) { LOG.finest( "pwBytes = " + ByteArrayHelper.toString(pwBytes) + " - " + pwBytes.length ); LOG.finest( "salt = " + ByteArrayHelper.toString(saltBytes) + " - " + saltBytes.length ); LOG.finest( "pwVerif = " + ByteArrayHelper.toString(pwVerificationBytes) + " - " + pwVerificationBytes.length ); } }
private static String hash(String str, byte[] salt, int iter) { PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(new SHA256Digest()); gen.init(str.getBytes(StandardCharsets.UTF_8), salt, iter); byte[] dk = ((KeyParameter) gen.generateDerivedParameters(KEY_LENGTH)).getKey(); return Base64.encodeBase64String(dk); }