116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropackage org.bouncycastle.jcajce.provider.symmetric.util; 216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 364fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giroimport java.lang.reflect.Method; 4bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giroimport java.security.InvalidAlgorithmParameterException; 516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport java.security.spec.AlgorithmParameterSpec; 616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 7bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giroimport javax.crypto.SecretKey; 864fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro// BEGIN android-added 964fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giroimport javax.crypto.spec.IvParameterSpec; 1064fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro// END android-added 1116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.spec.PBEKeySpec; 1216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport javax.crypto.spec.PBEParameterSpec; 1316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 1416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.CipherParameters; 1516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.PBEParametersGenerator; 167dad97b63c47edea4e3afb374dcd00c7b7a1bdd4Sergio Giro// BEGIN android-added 177dad97b63c47edea4e3afb374dcd00c7b7a1bdd4Sergio Giroimport org.bouncycastle.crypto.digests.AndroidDigestFactory; 187dad97b63c47edea4e3afb374dcd00c7b7a1bdd4Sergio Giro// END android-added 19c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// BEGIN android-removed 20c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import org.bouncycastle.crypto.digests.GOST3411Digest; 21c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import org.bouncycastle.crypto.digests.MD2Digest; 22c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import org.bouncycastle.crypto.digests.RIPEMD160Digest; 23c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// import org.bouncycastle.crypto.digests.TigerDigest; 24c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro// END android-removed 2516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator; 2616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; 2716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.generators.PKCS5S1ParametersGenerator; 2816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator; 2916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.DESParameters; 3016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.KeyParameter; 3116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giroimport org.bouncycastle.crypto.params.ParametersWithIV; 327dad97b63c47edea4e3afb374dcd00c7b7a1bdd4Sergio Giro// BEGIN android-removed 337dad97b63c47edea4e3afb374dcd00c7b7a1bdd4Sergio Giro// import org.bouncycastle.crypto.util.DigestFactory; 347dad97b63c47edea4e3afb374dcd00c7b7a1bdd4Sergio Giro// END android-removed 3516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 3616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giropublic interface PBE 3716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro{ 3816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // 3916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // PBE Based encryption constants - by default we do PKCS12 with SHA-1 4016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro // 4116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro static final int MD5 = 0; 4216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro static final int SHA1 = 1; 43c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-removed 44c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // static final int RIPEMD160 = 2; 45c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // static final int TIGER = 3; 46c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-removed 4716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro static final int SHA256 = 4; 48c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-removed 49c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // static final int MD2 = 5; 50c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // static final int GOST3411 = 6; 51c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-removed 524caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro static final int SHA224 = 7; 534caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro static final int SHA384 = 8; 544caba4cfca3316673ae4e330e8a47932bed8a53aSergio Giro static final int SHA512 = 9; 5516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 5616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro static final int PKCS5S1 = 0; 5716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro static final int PKCS5S2 = 1; 5816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro static final int PKCS12 = 2; 5916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro static final int OPENSSL = 3; 6016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro static final int PKCS5S1_UTF8 = 4; 6116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro static final int PKCS5S2_UTF8 = 5; 625c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro 6316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 6416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro /** 6516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * uses the appropriate mixer to generate the key and IV if necessary. 6616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro */ 6716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro static class Util 6816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 6916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro static private PBEParametersGenerator makePBEGenerator( 7016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int type, 7116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int hash) 7216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 7316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro PBEParametersGenerator generator; 7416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 7516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (type == PKCS5S1 || type == PKCS5S1_UTF8) 7616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 7716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro switch (hash) 7816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 79c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-removed 80c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // case MD2: 81c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // generator = new PKCS5S1ParametersGenerator(new MD2Digest()); 82c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // break; 83c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-removed 8416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro case MD5: 85c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-changed 86c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro generator = new PKCS5S1ParametersGenerator(AndroidDigestFactory.getMD5()); 87c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-changed 8816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro break; 8916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro case SHA1: 90c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-changed 91c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro generator = new PKCS5S1ParametersGenerator(AndroidDigestFactory.getSHA1()); 92c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-changed 9316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro break; 9416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro default: 9516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new IllegalStateException("PKCS5 scheme 1 only supports MD2, MD5 and SHA1."); 9616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 9716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 9816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (type == PKCS5S2 || type == PKCS5S2_UTF8) 9916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 10080261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro switch (hash) 10180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro { 102c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-removed 103c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // case MD2: 104c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // generator = new PKCS5S2ParametersGenerator(new MD2Digest()); 105c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // break; 106c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-removed 10780261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro case MD5: 108c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-changed 109c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getMD5()); 110c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-changed 11180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro break; 1127dad97b63c47edea4e3afb374dcd00c7b7a1bdd4Sergio Giro 11380261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro case SHA1: 114c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-changed 115c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA1()); 116c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-changed 117c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro break; 118c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-removed 119c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // case RIPEMD160: 120c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // generator = new PKCS5S2ParametersGenerator(new RIPEMD160Digest()); 121c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // break; 122c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // case TIGER: 123c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // generator = new PKCS5S2ParametersGenerator(new TigerDigest()); 124c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // break; 125c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-removed 1265c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro // BEGIN android-added 1275c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro case SHA224: 1285c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA224()); 1295c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro break; 1305c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro // END android-added 13180261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro case SHA256: 132c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-changed 133c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA256()); 134c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-changed 135c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro break; 1365c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro // BEGIN android-added 1375c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro case SHA384: 1385c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA384()); 1395c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro break; 1405c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro case SHA512: 1415c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro generator = new PKCS5S2ParametersGenerator(AndroidDigestFactory.getSHA512()); 1425c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro break; 1435c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro // END android-added 14480261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro default: 14580261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro throw new IllegalStateException("unknown digest scheme for PBE PKCS5S2 encryption."); 14680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro } 14716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 14816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (type == PKCS12) 14916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 15016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro switch (hash) 15116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 152c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-removed 153c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // case MD2: 154c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // generator = new PKCS12ParametersGenerator(new MD2Digest()); 155c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // break; 156c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-removed 15716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro case MD5: 158c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-changed 159c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getMD5()); 160c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-changed 16116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro break; 16216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro case SHA1: 163c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-changed 164c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA1()); 165c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-changed 166c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro break; 167c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-removed 168c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // case RIPEMD160: 169c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // generator = new PKCS12ParametersGenerator(new RIPEMD160Digest()); 170c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // break; 171c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // case TIGER: 172c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // generator = new PKCS12ParametersGenerator(new TigerDigest()); 173c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // break; 174c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-removed 1755c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro // BEGIN android-added 1765c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro case SHA224: 1775c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA224()); 1785c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro break; 1795c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro // END android-added 18016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro case SHA256: 181c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // BEGIN android-changed 182c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA256()); 183c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro // END android-changed 184c1040cb5656c3299f1c2d0fe0bd7c44b10466aafSergio Giro break; 1855c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro // BEGIN android-added 1865c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro case SHA384: 1875c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA384()); 1885c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro break; 1895c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro case SHA512: 1905c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro generator = new PKCS12ParametersGenerator(AndroidDigestFactory.getSHA512()); 1915c39dfb0425106172f6ee6d5f38083d3ec2f266dSergio Giro break; 19216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro default: 19316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new IllegalStateException("unknown digest scheme for PBE encryption."); 19416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 19516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 19616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 19716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 19816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro generator = new OpenSSLPBEParametersGenerator(); 19916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 20016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 20116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return generator; 20216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 20316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 20416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro /** 205bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro * construct a key and iv (if necessary) suitable for use with a 206bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro * Cipher. 207bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro */ 208bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro public static CipherParameters makePBEParameters( 209bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro byte[] pbeKey, 210bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro int scheme, 211bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro int digest, 212bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro int keySize, 213bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro int ivSize, 214bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro AlgorithmParameterSpec spec, 215bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro String targetAlgorithm) 216bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro throws InvalidAlgorithmParameterException 217bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro { 218bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro if ((spec == null) || !(spec instanceof PBEParameterSpec)) 219bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro { 220bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro throw new InvalidAlgorithmParameterException("Need a PBEParameter spec with a PBE key."); 221bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro } 222bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 223bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro PBEParameterSpec pbeParam = (PBEParameterSpec)spec; 224bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro PBEParametersGenerator generator = makePBEGenerator(scheme, digest); 225bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro byte[] key = pbeKey; 226bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro CipherParameters param; 227bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 228bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro// if (pbeKey.shouldTryWrongPKCS12()) 229bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro// { 230bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro// key = new byte[2]; 231bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro// } 232bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 233bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount()); 234bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 235bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro if (ivSize != 0) 236bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro { 237bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro param = generator.generateDerivedParameters(keySize, ivSize); 23864fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro // BEGIN ANDROID-ADDED 23964fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro // PKCS5S2 doesn't specify that the IV must be generated from the password. If the 24064fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro // IV is passed as a parameter, use it. 24164fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro AlgorithmParameterSpec parameterSpecFromPBEParameterSpec = 24264fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro getParameterSpecFromPBEParameterSpec(pbeParam); 24364fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro if ((scheme == PKCS5S2 || scheme == PKCS5S2_UTF8) 24464fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro && parameterSpecFromPBEParameterSpec instanceof IvParameterSpec) { 24564fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro ParametersWithIV parametersWithIV = (ParametersWithIV) param; 24664fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro IvParameterSpec ivParameterSpec = 24764fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro (IvParameterSpec) parameterSpecFromPBEParameterSpec; 24864fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro param = new ParametersWithIV( 24964fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro (KeyParameter) parametersWithIV.getParameters(), 25064fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro ivParameterSpec.getIV()); 25164fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro } 25264fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro // END ANDROID-ADDED 253bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro } 254bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro else 255bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro { 256bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro param = generator.generateDerivedParameters(keySize); 257bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro } 258bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 259bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro if (targetAlgorithm.startsWith("DES")) 260bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro { 261bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro if (param instanceof ParametersWithIV) 262bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro { 263bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro KeyParameter kParam = (KeyParameter)((ParametersWithIV)param).getParameters(); 264bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 265bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro DESParameters.setOddParity(kParam.getKey()); 266bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro } 267bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro else 268bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro { 269bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro KeyParameter kParam = (KeyParameter)param; 270bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 271bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro DESParameters.setOddParity(kParam.getKey()); 272bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro } 273bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro } 274bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 275bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro return param; 276bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro } 277bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 278bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro /** 27916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * construct a key and iv (if necessary) suitable for use with a 28016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * Cipher. 28116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro */ 28216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public static CipherParameters makePBEParameters( 28316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro BCPBEKey pbeKey, 28416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro AlgorithmParameterSpec spec, 28516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro String targetAlgorithm) 28616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 28716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if ((spec == null) || !(spec instanceof PBEParameterSpec)) 28816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 28916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key."); 29016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 29116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 29216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro PBEParameterSpec pbeParam = (PBEParameterSpec)spec; 29316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro PBEParametersGenerator generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest()); 29416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] key = pbeKey.getEncoded(); 29516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro CipherParameters param; 29616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 29716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (pbeKey.shouldTryWrongPKCS12()) 29816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 29916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro key = new byte[2]; 30016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 30116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 30216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount()); 30316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 30416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (pbeKey.getIvSize() != 0) 30516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 30616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = generator.generateDerivedParameters(pbeKey.getKeySize(), pbeKey.getIvSize()); 30764fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro // BEGIN ANDROID-ADDED 30864fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro // PKCS5S2 doesn't specify that the IV must be generated from the password. If the 30964fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro // IV is passed as a parameter, use it. 31064fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro AlgorithmParameterSpec parameterSpecFromPBEParameterSpec = 31164fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro getParameterSpecFromPBEParameterSpec(pbeParam); 31264fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro if ((pbeKey.getType() == PKCS5S2 || pbeKey.getType() == PKCS5S2_UTF8) 31364fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro && parameterSpecFromPBEParameterSpec instanceof IvParameterSpec) { 31464fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro ParametersWithIV parametersWithIV = (ParametersWithIV) param; 31564fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro IvParameterSpec ivParameterSpec = 31664fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro (IvParameterSpec) parameterSpecFromPBEParameterSpec; 31764fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro param = new ParametersWithIV( 31864fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro (KeyParameter) parametersWithIV.getParameters(), 31964fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro ivParameterSpec.getIV()); 32064fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro } 32164fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro // END ANDROID-ADDED 32216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 32316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 32416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 32516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = generator.generateDerivedParameters(pbeKey.getKeySize()); 32616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 32716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 32816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (targetAlgorithm.startsWith("DES")) 32916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 33016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (param instanceof ParametersWithIV) 33116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 33216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro KeyParameter kParam = (KeyParameter)((ParametersWithIV)param).getParameters(); 33316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 33416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DESParameters.setOddParity(kParam.getKey()); 33516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 33616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 33716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 33816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro KeyParameter kParam = (KeyParameter)param; 33916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 34016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro DESParameters.setOddParity(kParam.getKey()); 34116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 34216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 34316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 34416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return param; 34516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 34616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 34716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro /** 34816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * generate a PBE based key suitable for a MAC algorithm, the 34916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * key size is chosen according the MAC size, or the hashing algorithm, 35016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * whichever is greater. 35116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro */ 35216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public static CipherParameters makePBEMacParameters( 35316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro BCPBEKey pbeKey, 35416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro AlgorithmParameterSpec spec) 35516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 35616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if ((spec == null) || !(spec instanceof PBEParameterSpec)) 35716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 35816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro throw new IllegalArgumentException("Need a PBEParameter spec with a PBE key."); 35916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 36016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 36116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro PBEParameterSpec pbeParam = (PBEParameterSpec)spec; 36216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro PBEParametersGenerator generator = makePBEGenerator(pbeKey.getType(), pbeKey.getDigest()); 36316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] key = pbeKey.getEncoded(); 36416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro CipherParameters param; 36516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 36616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro generator.init(key, pbeParam.getSalt(), pbeParam.getIterationCount()); 36716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 36816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = generator.generateDerivedMacParameters(pbeKey.getKeySize()); 36916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 37016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return param; 37116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 372bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 373bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro /** 374bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro * generate a PBE based key suitable for a MAC algorithm, the 375bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro * key size is chosen according the MAC size, or the hashing algorithm, 376bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro * whichever is greater. 377bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro */ 378bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro public static CipherParameters makePBEMacParameters( 379bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro PBEKeySpec keySpec, 380bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro int type, 381bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro int hash, 382bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro int keySize) 383bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro { 384bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro PBEParametersGenerator generator = makePBEGenerator(type, hash); 385bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro byte[] key; 386bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro CipherParameters param; 387bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 388bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro key = convertPassword(type, keySpec); 389bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 390bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro generator.init(key, keySpec.getSalt(), keySpec.getIterationCount()); 391bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 392bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro param = generator.generateDerivedMacParameters(keySize); 393bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 394bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro for (int i = 0; i != key.length; i++) 395bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro { 396bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro key[i] = 0; 397bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro } 398bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 399bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro return param; 400bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro } 401bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro 40216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro /** 40316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * construct a key and iv (if necessary) suitable for use with a 40416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * Cipher. 40516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro */ 40616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public static CipherParameters makePBEParameters( 40716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro PBEKeySpec keySpec, 40816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int type, 40916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int hash, 41016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int keySize, 41116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int ivSize) 41216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 41316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro PBEParametersGenerator generator = makePBEGenerator(type, hash); 41416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] key; 41516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro CipherParameters param; 41616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 41716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro key = convertPassword(type, keySpec); 41816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 41916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro generator.init(key, keySpec.getSalt(), keySpec.getIterationCount()); 42016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 42116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (ivSize != 0) 42216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 42316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = generator.generateDerivedParameters(keySize, ivSize); 42416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 42516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 42616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 42716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = generator.generateDerivedParameters(keySize); 42816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 42916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 43016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro for (int i = 0; i != key.length; i++) 43116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 43216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro key[i] = 0; 43316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 43416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 43516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return param; 43616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 43716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 43816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro /** 43916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * generate a PBE based key suitable for a MAC algorithm, the 44016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * key size is chosen according the MAC size, or the hashing algorithm, 44116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro * whichever is greater. 44216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro */ 44316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro public static CipherParameters makePBEMacParameters( 444bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro SecretKey key, 44516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int type, 44616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro int hash, 447bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro int keySize, 448bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro PBEParameterSpec pbeSpec) 44916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 45016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro PBEParametersGenerator generator = makePBEGenerator(type, hash); 45116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro CipherParameters param; 45216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 453bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro byte[] keyBytes = key.getEncoded(); 45416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 455bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro generator.init(key.getEncoded(), pbeSpec.getSalt(), pbeSpec.getIterationCount()); 45680261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro 45716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro param = generator.generateDerivedMacParameters(keySize); 45880261dd2d1824bb3862e90e77a5412d56ad88b1fSergio Giro 459bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro for (int i = 0; i != keyBytes.length; i++) 46016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 461bdb7b3d37025690a0434040b4e0d0623d9fa74afSergio Giro keyBytes[i] = 0; 46216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 46316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 46416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return param; 46516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 46616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 46764fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro // BEGIN android-added 46864fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro /** 46964fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro * Invokes the method {@link PBEParameterSpec#getParameterSpec()} via reflection. 47064fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro * 47164fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro * Needed as the method was introduced in Java 1.8 and Bouncycastle level is 1.5. 47264fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro * 47364fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro * @return the parameter spec, or null if the method is not available. 47464fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro */ 47564fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro public static AlgorithmParameterSpec getParameterSpecFromPBEParameterSpec( 47664fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro PBEParameterSpec pbeParameterSpec) { 47764fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro try { 47864fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro Method getParameterSpecMethod = PBE.class.getClassLoader() 47964fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro .loadClass("javax.crypto.spec.PBEParameterSpec") 48064fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro .getMethod("getParameterSpec"); 48164fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro return (AlgorithmParameterSpec) getParameterSpecMethod.invoke(pbeParameterSpec); 48264fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro } catch (Exception e) { 48364fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro return null; 48464fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro } 48564fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro } 48664fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro // END android-added 48764fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro 48864fe4be2b2c98b1231314c785da2c050eccfe99bSergio Giro 48916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro private static byte[] convertPassword(int type, PBEKeySpec keySpec) 49016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 49116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro byte[] key; 49216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro 49316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro if (type == PKCS12) 49416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 49516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro key = PBEParametersGenerator.PKCS12PasswordToBytes(keySpec.getPassword()); 49616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 49716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else if (type == PKCS5S2_UTF8 || type == PKCS5S1_UTF8) 49816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 49916f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro key = PBEParametersGenerator.PKCS5PasswordToUTF8Bytes(keySpec.getPassword()); 50016f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 50116f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro else 50216f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro { 50316f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro key = PBEParametersGenerator.PKCS5PasswordToBytes(keySpec.getPassword()); 50416f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 50516f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro return key; 50616f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 50716f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro } 50816f9ee464b68937f45d009d9c1b0eb9b544a8deeSergio Giro} 509