PBE.java revision 2768c2948c0b1931bff087e43a8db8059c183b56
1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)package org.bouncycastle.jcajce.provider.symmetric.util;
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import java.security.spec.AlgorithmParameterSpec;
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import javax.crypto.spec.PBEKeySpec;
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import javax.crypto.spec.PBEParameterSpec;
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import org.bouncycastle.crypto.CipherParameters;
9a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import org.bouncycastle.crypto.PBEParametersGenerator;
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// BEGIN android-removed
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// import org.bouncycastle.crypto.digests.GOST3411Digest;
12a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// import org.bouncycastle.crypto.digests.MD2Digest;
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// import org.bouncycastle.crypto.digests.MD5Digest;
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// import org.bouncycastle.crypto.digests.RIPEMD160Digest;
1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)// import org.bouncycastle.crypto.digests.SHA1Digest;
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// import org.bouncycastle.crypto.digests.SHA256Digest;
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// import org.bouncycastle.crypto.digests.TigerDigest;
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// END android-removed
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// BEGIN android-added
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import org.bouncycastle.crypto.digests.AndroidDigestFactory;
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// END android-added
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator;
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
24a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator;
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import org.bouncycastle.crypto.params.DESParameters;
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import org.bouncycastle.crypto.params.KeyParameter;
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import org.bouncycastle.crypto.params.ParametersWithIV;
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)public interface PBE
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles){
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    //
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // PBE Based encryption constants - by default we do PKCS12 with SHA-1
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    //
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    static final int        MD5         = 0;
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    static final int        SHA1        = 1;
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // BEGIN android-removed
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // static final int        RIPEMD160   = 2;
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // static final int        TIGER       = 3;
400529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // END android-removed
410529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    static final int        SHA256      = 4;
420529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // BEGIN android-removed
430529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // static final int        MD2         = 5;
440529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    // static final int        GOST3411    = 6;
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // END android-removed
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
470529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    static final int        PKCS5S1     = 0;
480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    static final int        PKCS5S2     = 1;
49a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    static final int        PKCS12      = 2;
50a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    static final int        OPENSSL     = 3;
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // BEGIN android-added
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    static final int        PBKDF2      = 4;
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    // END android-added
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    /**
5623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)     * uses the appropriate mixer to generate the key and IV if necessary.
5723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)     */
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    static class Util
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    {
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        static private PBEParametersGenerator makePBEGenerator(
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            int                     type,
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            int                     hash)
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        {
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            PBEParametersGenerator  generator;
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            if (type == PKCS5S1)
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            {
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                switch (hash)
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                {
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                // BEGIN android-removed
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                // case MD2:
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                //     generator = new PKCS5S1ParametersGenerator(new MD2Digest());
73a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                //     break;
74a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                // END android-removed
75a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                case MD5:
76a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    // BEGIN android-changed
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    generator = new PKCS5S1ParametersGenerator(AndroidDigestFactory.getMD5());
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    // END android-changed
79a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    break;
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                case SHA1:
81a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    // BEGIN android-changed
82a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    generator = new PKCS5S1ParametersGenerator(AndroidDigestFactory.getSHA1());
83a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    // END android-changed
84a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    break;
85a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                default:
86a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    throw new IllegalStateException("PKCS5 scheme 1 only supports MD2, MD5 and SHA1.");
87a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                }
88a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            }
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            // BEGIN android-changed
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            else if ((type == PKCS5S2) || (type == PBKDF2))
91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            // END android-changed
92a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            {
93a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                generator = new PKCS5S2ParametersGenerator();
94a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            }
95a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            else if (type == PKCS12)
96a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            {
97a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                switch (hash)
98a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                {
99a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                // BEGIN android-removed
100a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                // case MD2:
101a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                //     generator = new PKCS12ParametersGenerator(new MD2Digest());
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                //     break;
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                // END android-removed
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                case MD5:
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    // BEGIN android-changed
106a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getMD5());
107a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    // END android-changed
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    break;
109a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                case SHA1:
110a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    // BEGIN android-changed
111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA1());
112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    // END android-changed
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    break;
114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                // BEGIN android-removed
115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                // case RIPEMD160:
116a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                //     generator = new PKCS12ParametersGenerator(new RIPEMD160Digest());
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                //     break;
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                // case TIGER:
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                //     generator = new PKCS12ParametersGenerator(new TigerDigest());
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                //     break;
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                // END android-removed
122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                case SHA256:
123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    // BEGIN android-changed
124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA256());
125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    // END android-changed
126a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    break;
127a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                // BEGIN android-removed
128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                // case GOST3411:
129a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                //     generator = new PKCS12ParametersGenerator(new GOST3411Digest());
130a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                //     break;
131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                // END android-removed
132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                default:
133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    throw new IllegalStateException("unknown digest scheme for PBE encryption.");
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                }
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            }
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            else
137a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            {
138a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                generator = new OpenSSLPBEParametersGenerator();
139a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            }
140a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
141a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            return generator;
142a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        }
143a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
144a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        /**
145a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         * construct a key and iv (if necessary) suitable for use with a
146a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         * Cipher.
147a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         */
148a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        public static CipherParameters makePBEParameters(
149a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            BCPBEKey pbeKey,
150a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            AlgorithmParameterSpec spec,
151a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            String targetAlgorithm)
152a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        {
153a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            if ((spec == null) || !(spec instanceof PBEParameterSpec))
154a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            {
155a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key.");
156a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)            }
157
158            PBEParameterSpec        pbeParam = (PBEParameterSpec)spec;
159            PBEParametersGenerator  generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest());
160            byte[]                  key = pbeKey.getEncoded();
161            CipherParameters        param;
162
163            if (pbeKey.shouldTryWrongPKCS12())
164            {
165                key = new byte[2];
166            }
167
168            generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount());
169
170            if (pbeKey.getIvSize() != 0)
171            {
172                param = generator.generateDerivedParameters(pbeKey.getKeySize(), pbeKey.getIvSize());
173            }
174            else
175            {
176                param = generator.generateDerivedParameters(pbeKey.getKeySize());
177            }
178
179            if (targetAlgorithm.startsWith("DES"))
180            {
181                if (param instanceof ParametersWithIV)
182                {
183                    KeyParameter    kParam = (KeyParameter)((ParametersWithIV)param).getParameters();
184
185                    DESParameters.setOddParity(kParam.getKey());
186                }
187                else
188                {
189                    KeyParameter    kParam = (KeyParameter)param;
190
191                    DESParameters.setOddParity(kParam.getKey());
192                }
193            }
194
195            for (int i = 0; i != key.length; i++)
196            {
197                key[i] = 0;
198            }
199
200            return param;
201        }
202
203        /**
204         * generate a PBE based key suitable for a MAC algorithm, the
205         * key size is chosen according the MAC size, or the hashing algorithm,
206         * whichever is greater.
207         */
208        public static CipherParameters makePBEMacParameters(
209            BCPBEKey pbeKey,
210            AlgorithmParameterSpec spec)
211        {
212            if ((spec == null) || !(spec instanceof PBEParameterSpec))
213            {
214                throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key.");
215            }
216
217            PBEParameterSpec        pbeParam = (PBEParameterSpec)spec;
218            PBEParametersGenerator  generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest());
219            byte[]                  key = pbeKey.getEncoded();
220            CipherParameters        param;
221
222            if (pbeKey.shouldTryWrongPKCS12())
223            {
224                key = new byte[2];
225            }
226
227            generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount());
228
229            param = generator.generateDerivedMacParameters(pbeKey.getKeySize());
230
231            for (int i = 0; i != key.length; i++)
232            {
233                key[i] = 0;
234            }
235
236            return param;
237        }
238
239        /**
240         * construct a key and iv (if necessary) suitable for use with a
241         * Cipher.
242         */
243        public static CipherParameters makePBEParameters(
244            PBEKeySpec keySpec,
245            int type,
246            int hash,
247            int keySize,
248            int ivSize)
249        {
250            PBEParametersGenerator  generator = makePBEGenerator(type, hash);
251            byte[]                  key;
252            CipherParameters        param;
253
254            if (type == PKCS12)
255            {
256                key = PBEParametersGenerator.PKCS12PasswordToBytes(keySpec.getPassword());
257            }
258            // BEGIN android-changed
259            else if (type == PBKDF2)
260            {
261                key = PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(keySpec.getPassword());
262            }
263            // END android-changed
264            else
265            {
266                key = PBEParametersGenerator.PKCS5PasswordToBytes(keySpec.getPassword());
267            }
268
269            generator.init(key, keySpec.getSalt(), keySpec.getIterationCount());
270
271            if (ivSize != 0)
272            {
273                param = generator.generateDerivedParameters(keySize, ivSize);
274            }
275            else
276            {
277                param = generator.generateDerivedParameters(keySize);
278            }
279
280            for (int i = 0; i != key.length; i++)
281            {
282                key[i] = 0;
283            }
284
285            return param;
286        }
287
288        /**
289         * generate a PBE based key suitable for a MAC algorithm, the
290         * key size is chosen according the MAC size, or the hashing algorithm,
291         * whichever is greater.
292         */
293        public static CipherParameters makePBEMacParameters(
294            PBEKeySpec keySpec,
295            int type,
296            int hash,
297            int keySize)
298        {
299            PBEParametersGenerator  generator = makePBEGenerator(type, hash);
300            byte[]                  key;
301            CipherParameters        param;
302
303            if (type == PKCS12)
304            {
305                key = PBEParametersGenerator.PKCS12PasswordToBytes(keySpec.getPassword());
306            }
307            // BEGIN android-changed
308            else if (type == PBKDF2)
309            {
310                key = PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(keySpec.getPassword());
311            }
312            // END android-changed
313            else
314            {
315                key = PBEParametersGenerator.PKCS5PasswordToBytes(keySpec.getPassword());
316            }
317
318            generator.init(key, keySpec.getSalt(), keySpec.getIterationCount());
319
320            param = generator.generateDerivedMacParameters(keySize);
321
322            for (int i = 0; i != key.length; i++)
323            {
324                key[i] = 0;
325            }
326
327            return param;
328        }
329    }
330}
331