1/* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16package libcore.javax.crypto.spec; 17 18import java.security.AlgorithmParameters; 19import java.security.Key; 20import java.util.Arrays; 21 22import junit.framework.TestCase; 23 24import javax.crypto.Cipher; 25import javax.crypto.SecretKeyFactory; 26import javax.crypto.spec.IvParameterSpec; 27import javax.crypto.spec.PBEKeySpec; 28import javax.crypto.spec.PBEParameterSpec; 29 30public class AlgorithmParametersTestPBES2 extends TestCase { 31 32 private static final int[] KEY_SIZES = { 128, 256 }; 33 int[] SHA_VARIANTS = { 1, 224, 256, 384, 512 }; 34 35 private static final PBEParameterSpec TEST_PBE_PARAMETER_SPEC = new PBEParameterSpec( 36 new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }, // salt 37 34, // iterationCount 38 new IvParameterSpec(new byte[] { 39 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55 // IV 40 })); 41 42 // For SHA variants other than SHA1, known answers generated with: 43 // 44 // AlgorithmParameters ap = AlgorithmParameters.getInstance( 45 // "PBEWithHmacSHA" + shaVariant + "AndAES_" + keySize, 46 // new com.sun.crypto.provider.SunJCE()); 47 // AlgorithmParameterSpec spec = TEST_PBE_PARAMETER_SPEC; 48 // ap.init(spec); 49 // System.out.println("Encoded: " + Arrays.toString(ap.getEncoded())); 50 // 51 // For SHA1, the RI does encode the prf (SHA1) although it is the default one, and thus it 52 // shouldn't be explicitly encoded, according to DER. Checked with an ASN1 decoder that the 53 // only difference between our encoding and the RI's one is that SHA1 is not explicitly 54 // encoded. 55 private static final byte[][] GET_ENCODED_KNOWN_ANSWERS = new byte[][] { 56 // PBEWithHmacSHA1AndAES_128 57 { 48, 75, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 62, 48, 29, 6, 9, 42, -122, 72, 58 -122, -9, 13, 1, 5, 12, 48, 16, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 16, 59 48, 29, 6, 9, 96, -122, 72, 1, 101, 3, 4, 1, 2, 4, 16, 40, 41, 42, 43, 44, 45, 46, 60 47, 48, 49, 50, 51, 52, 53, 54, 55 }, 61 // PBEWithHmacSHA224AndAES_128 62 { 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72, 63 -122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 16, 64 48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 8, 5, 0, 48, 29, 6, 9, 96, -122, 72, 1, 65 101, 3, 4, 1, 2, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 66 55 }, 67 // PBEWithHmacSHA256AndAES_128 68 { 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72, 69 -122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 16, 70 48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 9, 5, 0, 48, 29, 6, 9, 96, -122, 72, 1, 71 101, 3, 4, 1, 2, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 72 55 }, 73 // PBEWithHmacSHA384AndAES_128 74 { 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72, 75 -122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 16, 76 48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 10, 5, 0, 48, 29, 6, 9, 96, -122, 72, 77 1, 101, 3, 4, 1, 2, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 78 54, 55 }, 79 // PBEWithHmacSHA512AndAES_128 80 { 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72, 81 -122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 16, 82 48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 11, 5, 0, 48, 29, 6, 9, 96, -122, 72, 83 1, 101, 3, 4, 1, 2, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 84 54, 55 }, 85 // PBEWithHmacSHA1AndAES_256 86 { 48, 75, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 62, 48, 29, 6, 9, 42, -122, 72, 87 -122, -9, 13, 1, 5, 12, 48, 16, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 32, 88 48, 29, 6, 9, 96, -122, 72, 1, 101, 3, 4, 1, 42, 4, 16, 40, 41, 42, 43, 44, 45, 46, 89 47, 48, 49, 50, 51, 52, 53, 54, 55}, 90 // PBEWithHmacSHA224AndAES_256 91 { 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72, 92 -122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 32, 93 48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 8, 5, 0, 48, 29, 6, 9, 96, -122, 72, 1, 94 101, 3, 4, 1, 42, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 95 55 }, 96 // PBEWithHmacSHA256AndAES_256 97 { 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72, 98 -122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 32, 99 48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 9, 5, 0, 48, 29, 6, 9, 96, -122, 72, 1, 100 101, 3, 4, 1, 42, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 101 55 }, 102 // PBEWithHmacSHA384AndAES_256 103 { 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72, 104 -122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 32, 105 48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 10, 5, 0, 48, 29, 6, 9, 96, -122, 72, 106 1, 101, 3, 4, 1, 42, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 107 54, 55 }, 108 // PBEWithHmacSHA512AndAES_256 109 { 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72, 110 -122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 32, 111 48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 11, 5, 0, 48, 29, 6, 9, 96, -122, 72, 112 1, 101, 3, 4, 1, 42, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 113 54, 55 } }; 114 115 // Known answers obtained with: 116 // String algorithmName = "PBEWithHmacSHA" + shaVariant + "AndAES_" + keySize; 117 // SecretKeyFactory skf = SecretKeyFactory.getInstance( 118 // algorithmName, sunProvider); 119 // Key key = skf.generateSecret(pbeKS); 120 // Cipher c = Cipher.getInstance(algorithmName, sunProvider); 121 // c.init(Cipher.ENCRYPT_MODE, key, TEST_PBE_PARAMETER_SPEC); 122 // byte[] encrypted = c.doFinal(plaintext); 123 private static final byte[][] ENCRYPT_KNOWN_ANSWERS = new byte[][]{ 124 // PBEWithHmacSHA1AndAES_128 125 { -42, -84, 94, -75, -84, 12, -83, -100, -76, -58, -78, 82, -78, 11, -70, 67, 92, 111, -90, 126 -75, 43, 31, 16, 47, -81, -127, -65, -127, -41, 121, 77, -90, -15, 3, 5, -12, 66, 127 37, -80, 107, -99, 106, -59, -79, -32, -7, -27, 110 }, 128 { 121, 36, -19, 19, -89, 95, -15, 50, -62, 36, -23, -78, -7, 43, 79, -31, 17, 88, -35, -89, 129 -11, 108, -8, -64, 77, 57, 64, 36, 70, -102, -65, 77, 74, 20, 9, -121, -9, 69, -115, 130 21, 32, -22, -107, -75, -76, 111, 79, 99 }, 131 // PBEWithHmacSHA224AndAES_128 132 { 1, 60, 84, 10, 3, 110, 3, -112, 27, 126, 59, -63, -34, 117, 83, -67, -115, 117, -23, 57, 133 -70, -126, 57, -84, -3, -102, -87, 98, 77, 10, -19, -41, 20, -95, 53, -112, -48, 22, 134 22, -99, -71, -88, -111, -87, 3, -126, -83, 64 }, 135 // PBEWithHmacSHA256AndAES_128 136 { -102, -122, 69, -75, -11, -61, -13, 82, 122, -97, 112, -27, 61, 22, -28, -34, -66, -47, 137 123, 104, 20, -115, 83, -33, -38, 65, -101, -128, -20, -34, 95, 53, -69, 11, -79, 138 -78, 37, 2, -81, 126, 97, -10, -69, -56, 89, -22, -25, -72 }, 139 // PBEWithHmacSHA384AndAES_128 140 { -67, -57, -99, -6, 102, 87, -111, 18, 63, 7, -99, 32, -110, -24, 44, -94, -24, 101, 39, 141 115, 24, 20, -31, 126, 99, -113, -40, 27, 79, -48, 98, 84, 67, -51, 115, -21, -118, 142 9, 11, -117, -25, -73, -106, 36, -28, -18, 96, 16 }, 143 // PBEWithHmacSHA512AndAES_128 144 { -72, 97, -41, -80, 0, 39, -121, 107, -89, -72, -103, -52, 100, 126, -89, -59, -4, 73, 145 -116, 0, 69, 95, 23, -25, 67, -81, -23, 1, 18, 57, -73, 89, 79, 124, -128, -113, 12, 146 78, 14, 12, 64, 112, -105, -6, 13, -112, 26, -92 }, 147 // PBEWithHmacSHA1AndAES_256 148 { 98, 125, 91, -63, 96, 15, -103, -127, 70, -73, -25, 40, -126, 116, 15, -102, -108, 117, 149 -111, -65, -24, -114, 90, -126, -115, 15, -86, -72, -109, 47, 39, -102, -52, 123, 150 -4, -50, -99, 33, 92, 32, -110, -6, -2, -114, -116, 2, -16, -106 }, 151 // PBEWithHmacSHA256AndAES_256 152 { 126, -32, 53, 14, -13, 26, 127, -23, -38, -56, 66, 1, 45, -128, -16, -99, -34, -31, -49, 153 126, 120, -47, -39, -108, -12, 16, 16, -127, 64, -64, 75, 53, 41, 51, 53, -37, -95, 154 3, -87, -100, 103, -55, 30, 5, 29, 8, 93, 123 }, 155 // PBEWithHmacSHA384AndAES_256 156 { 68, 99, -46, -114, 37, -29, 59, -80, 16, 113, 116, 97, -9, -36, -32, 8, 59, -124, -73, 157 -66, -105, -57, 41, -78, 86, -128, 90, 51, -29, 108, -24, -62, 87, 94, -87, -5, 126, 158 95, -101, -39, -126, -76, 77, -2, 44, -70, -70, -88 }, 159 // PBEWithHmacSHA512AndAES_256 160 { -93, -114, 1, -58, 117, -41, -114, 58, 56, 108, -16, -57, -36, -76, 92, -65, 100, 119, -9, 161 8, -93, 113, -3, -85, -31, -26, 20, 115, -45, -56, 30, 106, -16, -66, 4, -53, 2, 162 -113, 8, -116, -38, 0, 126, -87, 61, -32, 57, -35} 163 }; 164 165 public void testGetEncoded_knownAnswers() throws Exception { 166 int i = 0; 167 for (int keySize : KEY_SIZES) { 168 for (int shaVariant : SHA_VARIANTS) { 169 AlgorithmParameters ap = AlgorithmParameters.getInstance( 170 "PBEWithHmacSHA"+ shaVariant + "AndAES_" + keySize, "BC"); 171 ap.init(TEST_PBE_PARAMETER_SPEC); 172 assertEquals( 173 Arrays.toString(GET_ENCODED_KNOWN_ANSWERS[i]), 174 Arrays.toString(ap.getEncoded())); 175 i++; 176 } 177 } 178 } 179 180 public void test_encodeAndDecode() throws Exception { 181 AlgorithmParameters ap = AlgorithmParameters.getInstance( 182 "PBEWithHmacSHA224AndAES_128", "BC"); 183 ap.init(TEST_PBE_PARAMETER_SPEC); 184 AlgorithmParameters ap2 = AlgorithmParameters.getInstance( 185 "PBEWithHmacSHA224AndAES_128", "BC"); 186 ap2.init(ap.getEncoded()); 187 PBEParameterSpec encodedSpec = ap2.getParameterSpec(PBEParameterSpec.class); 188 assertEquals(Arrays.toString(TEST_PBE_PARAMETER_SPEC.getSalt()), 189 Arrays.toString(encodedSpec.getSalt())); 190 assertEquals(TEST_PBE_PARAMETER_SPEC.getIterationCount(), encodedSpec.getIterationCount()); 191 assertTrue(encodedSpec.getParameterSpec() instanceof IvParameterSpec); 192 assertEquals( 193 Arrays.toString( 194 ((IvParameterSpec) TEST_PBE_PARAMETER_SPEC.getParameterSpec()).getIV()), 195 Arrays.toString(((IvParameterSpec) encodedSpec.getParameterSpec()).getIV())); 196 } 197 198 public void test_encryptWithAlgorithmParameters() throws Exception { 199 byte[] plaintext = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 , 15, 16, 17, 18, 19, 200 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 }; 201 PBEKeySpec pbeKS = new PBEKeySpec("aaaaa".toCharArray()); 202 int i = 0; 203 for (int keySize : KEY_SIZES) { 204 for (int shaVariant : SHA_VARIANTS) { 205 String algorithmName = "PBEWithHmacSHA" + shaVariant + "AndAES_" + keySize; 206 AlgorithmParameters ap = AlgorithmParameters.getInstance(algorithmName, "BC"); 207 ap.init(TEST_PBE_PARAMETER_SPEC); 208 SecretKeyFactory skf = SecretKeyFactory.getInstance( 209 algorithmName, "BC"); 210 Key key = skf.generateSecret(pbeKS); 211 Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC"); 212 c.init(Cipher.ENCRYPT_MODE, key, ap); 213 byte[] encrypted = c.doFinal(plaintext); 214 assertEquals( 215 Arrays.toString(ENCRYPT_KNOWN_ANSWERS[i]), 216 Arrays.toString(encrypted)); 217 c.init(Cipher.DECRYPT_MODE, key, ap); 218 byte[] decrypted = c.doFinal(encrypted); 219 assertEquals( 220 Arrays.toString(plaintext), 221 Arrays.toString(decrypted)); 222 i++; 223 } 224 } 225 } 226 227 public void test_correctNames() throws Exception { 228 for (int keySize : KEY_SIZES) { 229 for (int shaVariant : SHA_VARIANTS) { 230 String algorithmName = "PBEWithHmacSHA" + shaVariant + "AndAES_" + keySize; 231 AlgorithmParameters ap = AlgorithmParameters.getInstance(algorithmName, "BC"); 232 ap.init(TEST_PBE_PARAMETER_SPEC); 233 assertTrue(ap.toString().matches("(?i:.*hmacsha" + shaVariant + ".*)")); 234 assertTrue(ap.toString().matches("(?i:.*aes" + +keySize + ".*)")); 235 } 236 } 237 } 238 239 public void test_encryptWithNoSalt() throws Exception { 240 // Encrypting with no salt is allowed if using a PKCS5 scheme, which 241 // the SHA-based ones aren't but MD5-based ones are. 242 String algorithmName = "PBEwithMD5andDES"; 243 SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithmName, "BC"); 244 Key key = skf.generateSecret(new PBEKeySpec("aaaaa".toCharArray())); 245 Cipher c = Cipher.getInstance(algorithmName, "BC"); 246 c.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(new byte[0], 1000)); 247 } 248} 249