/** * generate a PBE based key suitable for a MAC algorithm, the key size is chosen according the * MAC size, or the hashing algorithm, whichever is greater. */ public static CipherParameters makePBEMacParameters( BCPBEKey pbeKey, AlgorithmParameterSpec spec) { if ((spec == null) || !(spec instanceof PBEParameterSpec)) { throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key."); } PBEParameterSpec pbeParam = (PBEParameterSpec) spec; PBEParametersGenerator generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest()); byte[] key = pbeKey.getEncoded(); CipherParameters param; if (pbeKey.shouldTryWrongPKCS12()) { key = new byte[2]; } generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount()); param = generator.generateDerivedMacParameters(pbeKey.getKeySize()); for (int i = 0; i != key.length; i++) { key[i] = 0; } return param; }
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[] convertPassword(int type, PBEKeySpec keySpec) { byte[] key; if (type == PKCS12) { key = PBEParametersGenerator.PKCS12PasswordToBytes(keySpec.getPassword()); } else if (type == PKCS5S2_UTF8 || type == PKCS5S1_UTF8) { key = PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(keySpec.getPassword()); } else { key = PBEParametersGenerator.PKCS5PasswordToBytes(keySpec.getPassword()); } return key; }
private static CipherParameters extractPBES2CipherParams( char[] password, PBES2Parameters pbeParams) { PBKDF2Params pbkdfParams = PBKDF2Params.getInstance(pbeParams.getKeyDerivationFunc().getParameters()); int keySize = 192; if (pbkdfParams.getKeyLength() != null) { keySize = pbkdfParams.getKeyLength().intValue() * 8; } int iterationCount = pbkdfParams.getIterationCount().intValue(); byte[] salt = pbkdfParams.getSalt(); PBEParametersGenerator generator = new PKCS5S2ParametersGenerator(); generator.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), salt, iterationCount); return generator.generateDerivedParameters(keySize); }
private static void writePemEncrypted( BufferedWriter out, String pemHeader, byte[] encoding, CipherSpec cipher, char[] passwd) throws IOException { Cipher c = cipher.getCipher(); byte[] iv = new byte[c.getBlockSize()]; random.nextBytes(iv); byte[] salt = new byte[8]; System.arraycopy(iv, 0, salt, 0, 8); OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator(); pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(passwd), salt); KeyParameter param = (KeyParameter) pGen.generateDerivedParameters(cipher.getKeyLenInBits()); SecretKey secretKey = new SecretKeySpec( param.getKey(), org.jruby.ext.openssl.Cipher.Algorithm.getAlgorithmBase(c)); byte[] encData = null; try { c.init(Cipher.ENCRYPT_MODE, secretKey, new IvParameterSpec(iv)); encData = c.doFinal(encoding); } catch (GeneralSecurityException gse) { throw new IOException("exception using cipher: " + gse.toString()); } out.write(BEF_G + pemHeader + AFT); out.newLine(); out.write("Proc-Type: 4,ENCRYPTED"); out.newLine(); out.write("DEK-Info: " + cipher.getOsslName() + ","); writeHexEncoded(out, iv); out.newLine(); out.newLine(); writeEncoded(out, encData); out.write(BEF_E + pemHeader + AFT); out.flush(); }
private static byte[] decrypt(byte[] decoded, String dekInfo, char[] passwd) throws IOException, GeneralSecurityException { if (passwd == null) { throw new IOException("Password is null, but a password is required"); } StringTokenizer tknz = new StringTokenizer(dekInfo, ","); String algorithm = tknz.nextToken(); byte[] iv = Hex.decode(tknz.nextToken()); if (!CipherModule.isSupportedCipher(algorithm)) { throw new IOException("Unknown algorithm: " + algorithm); } String[] cipher = org.jruby.ext.openssl.Cipher.Algorithm.osslToJsse(algorithm); String realName = cipher[3]; int[] lengths = org.jruby.ext.openssl.Cipher.Algorithm.osslKeyIvLength(algorithm); int keyLen = lengths[0]; int ivLen = lengths[1]; if (iv.length != ivLen) { throw new IOException("Illegal IV length"); } byte[] salt = new byte[8]; System.arraycopy(iv, 0, salt, 0, 8); OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator(); pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(passwd), salt); KeyParameter param = (KeyParameter) pGen.generateDerivedParameters(keyLen * 8); SecretKey secretKey = new javax.crypto.spec.SecretKeySpec(param.getKey(), realName); Cipher c = Cipher.getInstance(realName); c.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv)); return c.doFinal(decoded); }
/** * generate a PBE based key suitable for a MAC algorithm, the key size is chosen according the * MAC size, or the hashing algorithm, whichever is greater. */ public static CipherParameters makePBEMacParameters( PBEKeySpec keySpec, int type, int hash, int keySize) { PBEParametersGenerator generator = makePBEGenerator(type, hash); byte[] key; CipherParameters param; key = convertPassword(type, keySpec); generator.init(key, keySpec.getSalt(), keySpec.getIterationCount()); param = generator.generateDerivedMacParameters(keySize); for (int i = 0; i != key.length; i++) { key[i] = 0; } return param; }
/** construct a key and iv (if necessary) suitable for use with a Cipher. */ public static CipherParameters makePBEParameters( BCPBEKey pbeKey, AlgorithmParameterSpec spec, String targetAlgorithm) { if ((spec == null) || !(spec instanceof PBEParameterSpec)) { throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key."); } PBEParameterSpec pbeParam = (PBEParameterSpec) spec; PBEParametersGenerator generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest()); byte[] key = pbeKey.getEncoded(); CipherParameters param; if (pbeKey.shouldTryWrongPKCS12()) { key = new byte[2]; } generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount()); if (pbeKey.getIvSize() != 0) { param = generator.generateDerivedParameters(pbeKey.getKeySize(), pbeKey.getIvSize()); } else { param = generator.generateDerivedParameters(pbeKey.getKeySize()); } if (targetAlgorithm.startsWith("DES")) { if (param instanceof ParametersWithIV) { KeyParameter kParam = (KeyParameter) ((ParametersWithIV) param).getParameters(); DESParameters.setOddParity(kParam.getKey()); } else { KeyParameter kParam = (KeyParameter) param; DESParameters.setOddParity(kParam.getKey()); } } for (int i = 0; i != key.length; i++) { key[i] = 0; } return param; }
/** construct a key and iv (if necessary) suitable for use with a Cipher. */ public static CipherParameters makePBEParameters( PBEKeySpec keySpec, int type, int hash, int keySize, int ivSize) { PBEParametersGenerator generator = makePBEGenerator(type, hash); byte[] key; CipherParameters param; if (type == PKCS12) { key = PBEParametersGenerator.PKCS12PasswordToBytes(keySpec.getPassword()); } else { key = PBEParametersGenerator.PKCS5PasswordToBytes(keySpec.getPassword()); } generator.init(key, keySpec.getSalt(), keySpec.getIterationCount()); if (ivSize != 0) { param = generator.generateDerivedParameters(keySize, ivSize); } else { param = generator.generateDerivedParameters(keySize); } for (int i = 0; i != key.length; i++) { key[i] = 0; } return param; }
protected RecipientOperator getRecipientOperator(Recipient recipient) throws CMSException, IOException { PasswordRecipient pbeRecipient = (PasswordRecipient) recipient; AlgorithmIdentifier kekAlg = AlgorithmIdentifier.getInstance(info.getKeyEncryptionAlgorithm()); ASN1Sequence kekAlgParams = (ASN1Sequence) kekAlg.getParameters(); DERObjectIdentifier kekAlgName = DERObjectIdentifier.getInstance(kekAlgParams.getObjectAt(0)); PBKDF2Params params = PBKDF2Params.getInstance(info.getKeyDerivationAlgorithm().getParameters()); byte[] derivedKey; int keySize = ((Integer) KEYSIZES.get(kekAlgName)).intValue(); if (pbeRecipient.getPasswordConversionScheme() == PasswordRecipient.PKCS5_SCHEME2) { PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(); gen.init( PBEParametersGenerator.PKCS5PasswordToBytes(pbeRecipient.getPassword()), params.getSalt(), params.getIterationCount().intValue()); derivedKey = ((KeyParameter) gen.generateDerivedParameters(keySize)).getKey(); } else { PKCS5S2ParametersGenerator gen = new PKCS5S2ParametersGenerator(); gen.init( PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(pbeRecipient.getPassword()), params.getSalt(), params.getIterationCount().intValue()); derivedKey = ((KeyParameter) gen.generateDerivedParameters(keySize)).getKey(); } return pbeRecipient.getRecipientOperator( AlgorithmIdentifier.getInstance(kekAlg.getParameters()), messageAlgorithm, derivedKey, info.getEncryptedKey().getOctets()); }
private static SecretKey getKey( char[] password, String algorithm, int keyLength, byte[] salt, boolean des2) { OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator(); pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), salt); KeyParameter keyParam; keyParam = (KeyParameter) pGen.generateDerivedParameters(keyLength * 8); byte[] key = keyParam.getKey(); if (des2 && key.length >= 24) { // For DES2, we must copy first 8 bytes into the last 8 bytes. System.arraycopy(key, 0, key, 16, 8); } return new javax.crypto.spec.SecretKeySpec(key, algorithm); }