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