static MacCalculator createMacCalculator(final ASN1ObjectIdentifier digestAlgorithm, ExtendedDigest digest, final PKCS12PBEParams pbeParams, final char[] password) { PKCS12ParametersGenerator pGen = new PKCS12ParametersGenerator(digest); pGen.init(PKCS12ParametersGenerator.PKCS12PasswordToBytes(password), pbeParams.getIV(), pbeParams.getIterations().intValue()); final KeyParameter keyParam = (KeyParameter)pGen.generateDerivedMacParameters(digest.getDigestSize() * 8); final HMac hMac = new HMac(digest); hMac.init(keyParam); return new MacCalculator() { public AlgorithmIdentifier getAlgorithmIdentifier() { return new AlgorithmIdentifier(digestAlgorithm, pbeParams); } public OutputStream getOutputStream() { return new MacOutputStream(hMac); } public byte[] getMac() { byte[] res = new byte[hMac.getMacSize()]; hMac.doFinal(res, 0); return res; } public GenericKey getKey() { return new GenericKey(getAlgorithmIdentifier(), PKCS12ParametersGenerator.PKCS12PasswordToBytes(password)); } }; }
public void engineStore(OutputStream stream, char[] password) throws IOException { DataOutputStream dOut = new DataOutputStream(stream); byte[] salt = new byte[STORE_SALT_SIZE]; int iterationCount = MIN_ITERATIONS + (random.nextInt() & 0x3ff); random.nextBytes(salt); dOut.writeInt(version); dOut.writeInt(salt.length); dOut.write(salt); dOut.writeInt(iterationCount); HMac hMac = new HMac(new SHA1Digest()); MacOutputStream mOut = new MacOutputStream(hMac); PBEParametersGenerator pbeGen = new PKCS12ParametersGenerator(new SHA1Digest()); byte[] passKey = PBEParametersGenerator.PKCS12PasswordToBytes(password); pbeGen.init(passKey, salt, iterationCount); if (version < 2) { hMac.init(pbeGen.generateDerivedMacParameters(hMac.getMacSize())); } else { hMac.init(pbeGen.generateDerivedMacParameters(hMac.getMacSize() * 8)); } for (int i = 0; i != passKey.length; i++) { passKey[i] = 0; } saveStore(new TeeOutputStream(dOut, mOut)); byte[] mac = new byte[hMac.getMacSize()]; hMac.doFinal(mac, 0); dOut.write(mac); dOut.close(); }