blob: cf686b25093211f49dc5be31ba63fe91c102608d [file] [log] [blame]
/*
* Copyright (C) 2016 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License
*/
package libcore.javax.crypto.spec;
import java.security.AlgorithmParameters;
import java.security.Key;
import java.util.Arrays;
import junit.framework.TestCase;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.PBEParameterSpec;
public class AlgorithmParametersTestPBES2 extends TestCase {
private static final int[] KEY_SIZES = { 128, 256 };
int[] SHA_VARIANTS = { 1, 224, 256, 384, 512 };
private static final PBEParameterSpec TEST_PBE_PARAMETER_SPEC = new PBEParameterSpec(
new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 }, // salt
34, // iterationCount
new IvParameterSpec(new byte[] {
40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55 // IV
}));
// For SHA variants other than SHA1, known answers generated with:
//
// AlgorithmParameters ap = AlgorithmParameters.getInstance(
// "PBEWithHmacSHA" + shaVariant + "AndAES_" + keySize,
// new com.sun.crypto.provider.SunJCE());
// AlgorithmParameterSpec spec = TEST_PBE_PARAMETER_SPEC;
// ap.init(spec);
// System.out.println("Encoded: " + Arrays.toString(ap.getEncoded()));
//
// For SHA1, the RI does encode the prf (SHA1) although it is the default one, and thus it
// shouldn't be explicitly encoded, according to DER. Checked with an ASN1 decoder that the
// only difference between our encoding and the RI's one is that SHA1 is not explicitly
// encoded.
private static final byte[][] GET_ENCODED_KNOWN_ANSWERS = new byte[][] {
// PBEWithHmacSHA1AndAES_128
{ 48, 75, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 62, 48, 29, 6, 9, 42, -122, 72,
-122, -9, 13, 1, 5, 12, 48, 16, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 16,
48, 29, 6, 9, 96, -122, 72, 1, 101, 3, 4, 1, 2, 4, 16, 40, 41, 42, 43, 44, 45, 46,
47, 48, 49, 50, 51, 52, 53, 54, 55 },
// PBEWithHmacSHA224AndAES_128
{ 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72,
-122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 16,
48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 8, 5, 0, 48, 29, 6, 9, 96, -122, 72, 1,
101, 3, 4, 1, 2, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55 },
// PBEWithHmacSHA256AndAES_128
{ 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72,
-122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 16,
48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 9, 5, 0, 48, 29, 6, 9, 96, -122, 72, 1,
101, 3, 4, 1, 2, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55 },
// PBEWithHmacSHA384AndAES_128
{ 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72,
-122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 16,
48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 10, 5, 0, 48, 29, 6, 9, 96, -122, 72,
1, 101, 3, 4, 1, 2, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
54, 55 },
// PBEWithHmacSHA512AndAES_128
{ 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72,
-122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 16,
48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 11, 5, 0, 48, 29, 6, 9, 96, -122, 72,
1, 101, 3, 4, 1, 2, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
54, 55 },
// PBEWithHmacSHA1AndAES_256
{ 48, 75, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 62, 48, 29, 6, 9, 42, -122, 72,
-122, -9, 13, 1, 5, 12, 48, 16, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 32,
48, 29, 6, 9, 96, -122, 72, 1, 101, 3, 4, 1, 42, 4, 16, 40, 41, 42, 43, 44, 45, 46,
47, 48, 49, 50, 51, 52, 53, 54, 55},
// PBEWithHmacSHA224AndAES_256
{ 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72,
-122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 32,
48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 8, 5, 0, 48, 29, 6, 9, 96, -122, 72, 1,
101, 3, 4, 1, 42, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55 },
// PBEWithHmacSHA256AndAES_256
{ 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72,
-122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 32,
48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 9, 5, 0, 48, 29, 6, 9, 96, -122, 72, 1,
101, 3, 4, 1, 42, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
55 },
// PBEWithHmacSHA384AndAES_256
{ 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72,
-122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 32,
48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 10, 5, 0, 48, 29, 6, 9, 96, -122, 72,
1, 101, 3, 4, 1, 42, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
54, 55 },
// PBEWithHmacSHA512AndAES_256
{ 48, 89, 6, 9, 42, -122, 72, -122, -9, 13, 1, 5, 13, 48, 76, 48, 43, 6, 9, 42, -122, 72,
-122, -9, 13, 1, 5, 12, 48, 30, 4, 8, 0, 1, 2, 3, 4, 5, 6, 7, 2, 1, 34, 2, 1, 32,
48, 12, 6, 8, 42, -122, 72, -122, -9, 13, 2, 11, 5, 0, 48, 29, 6, 9, 96, -122, 72,
1, 101, 3, 4, 1, 42, 4, 16, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
54, 55 } };
// Known answers obtained with:
// String algorithmName = "PBEWithHmacSHA" + shaVariant + "AndAES_" + keySize;
// SecretKeyFactory skf = SecretKeyFactory.getInstance(
// algorithmName, sunProvider);
// Key key = skf.generateSecret(pbeKS);
// Cipher c = Cipher.getInstance(algorithmName, sunProvider);
// c.init(Cipher.ENCRYPT_MODE, key, TEST_PBE_PARAMETER_SPEC);
// byte[] encrypted = c.doFinal(plaintext);
private static final byte[][] ENCRYPT_KNOWN_ANSWERS = new byte[][]{
// PBEWithHmacSHA1AndAES_128
{ -42, -84, 94, -75, -84, 12, -83, -100, -76, -58, -78, 82, -78, 11, -70, 67, 92, 111, -90,
-75, 43, 31, 16, 47, -81, -127, -65, -127, -41, 121, 77, -90, -15, 3, 5, -12, 66,
37, -80, 107, -99, 106, -59, -79, -32, -7, -27, 110 },
{ 121, 36, -19, 19, -89, 95, -15, 50, -62, 36, -23, -78, -7, 43, 79, -31, 17, 88, -35, -89,
-11, 108, -8, -64, 77, 57, 64, 36, 70, -102, -65, 77, 74, 20, 9, -121, -9, 69, -115,
21, 32, -22, -107, -75, -76, 111, 79, 99 },
// PBEWithHmacSHA224AndAES_128
{ 1, 60, 84, 10, 3, 110, 3, -112, 27, 126, 59, -63, -34, 117, 83, -67, -115, 117, -23, 57,
-70, -126, 57, -84, -3, -102, -87, 98, 77, 10, -19, -41, 20, -95, 53, -112, -48, 22,
22, -99, -71, -88, -111, -87, 3, -126, -83, 64 },
// PBEWithHmacSHA256AndAES_128
{ -102, -122, 69, -75, -11, -61, -13, 82, 122, -97, 112, -27, 61, 22, -28, -34, -66, -47,
123, 104, 20, -115, 83, -33, -38, 65, -101, -128, -20, -34, 95, 53, -69, 11, -79,
-78, 37, 2, -81, 126, 97, -10, -69, -56, 89, -22, -25, -72 },
// PBEWithHmacSHA384AndAES_128
{ -67, -57, -99, -6, 102, 87, -111, 18, 63, 7, -99, 32, -110, -24, 44, -94, -24, 101, 39,
115, 24, 20, -31, 126, 99, -113, -40, 27, 79, -48, 98, 84, 67, -51, 115, -21, -118,
9, 11, -117, -25, -73, -106, 36, -28, -18, 96, 16 },
// PBEWithHmacSHA512AndAES_128
{ -72, 97, -41, -80, 0, 39, -121, 107, -89, -72, -103, -52, 100, 126, -89, -59, -4, 73,
-116, 0, 69, 95, 23, -25, 67, -81, -23, 1, 18, 57, -73, 89, 79, 124, -128, -113, 12,
78, 14, 12, 64, 112, -105, -6, 13, -112, 26, -92 },
// PBEWithHmacSHA1AndAES_256
{ 98, 125, 91, -63, 96, 15, -103, -127, 70, -73, -25, 40, -126, 116, 15, -102, -108, 117,
-111, -65, -24, -114, 90, -126, -115, 15, -86, -72, -109, 47, 39, -102, -52, 123,
-4, -50, -99, 33, 92, 32, -110, -6, -2, -114, -116, 2, -16, -106 },
// PBEWithHmacSHA256AndAES_256
{ 126, -32, 53, 14, -13, 26, 127, -23, -38, -56, 66, 1, 45, -128, -16, -99, -34, -31, -49,
126, 120, -47, -39, -108, -12, 16, 16, -127, 64, -64, 75, 53, 41, 51, 53, -37, -95,
3, -87, -100, 103, -55, 30, 5, 29, 8, 93, 123 },
// PBEWithHmacSHA384AndAES_256
{ 68, 99, -46, -114, 37, -29, 59, -80, 16, 113, 116, 97, -9, -36, -32, 8, 59, -124, -73,
-66, -105, -57, 41, -78, 86, -128, 90, 51, -29, 108, -24, -62, 87, 94, -87, -5, 126,
95, -101, -39, -126, -76, 77, -2, 44, -70, -70, -88 },
// PBEWithHmacSHA512AndAES_256
{ -93, -114, 1, -58, 117, -41, -114, 58, 56, 108, -16, -57, -36, -76, 92, -65, 100, 119, -9,
8, -93, 113, -3, -85, -31, -26, 20, 115, -45, -56, 30, 106, -16, -66, 4, -53, 2,
-113, 8, -116, -38, 0, 126, -87, 61, -32, 57, -35}
};
public void testGetEncoded_knownAnswers() throws Exception {
int i = 0;
for (int keySize : KEY_SIZES) {
for (int shaVariant : SHA_VARIANTS) {
AlgorithmParameters ap = AlgorithmParameters.getInstance(
"PBEWithHmacSHA"+ shaVariant + "AndAES_" + keySize, "BC");
ap.init(TEST_PBE_PARAMETER_SPEC);
assertEquals(
Arrays.toString(GET_ENCODED_KNOWN_ANSWERS[i]),
Arrays.toString(ap.getEncoded()));
i++;
}
}
}
public void test_encodeAndDecode() throws Exception {
AlgorithmParameters ap = AlgorithmParameters.getInstance(
"PBEWithHmacSHA224AndAES_128", "BC");
ap.init(TEST_PBE_PARAMETER_SPEC);
AlgorithmParameters ap2 = AlgorithmParameters.getInstance(
"PBEWithHmacSHA224AndAES_128", "BC");
ap2.init(ap.getEncoded());
PBEParameterSpec encodedSpec = ap2.getParameterSpec(PBEParameterSpec.class);
assertEquals(Arrays.toString(TEST_PBE_PARAMETER_SPEC.getSalt()),
Arrays.toString(encodedSpec.getSalt()));
assertEquals(TEST_PBE_PARAMETER_SPEC.getIterationCount(), encodedSpec.getIterationCount());
assertTrue(encodedSpec.getParameterSpec() instanceof IvParameterSpec);
assertEquals(
Arrays.toString(
((IvParameterSpec) TEST_PBE_PARAMETER_SPEC.getParameterSpec()).getIV()),
Arrays.toString(((IvParameterSpec) encodedSpec.getParameterSpec()).getIV()));
}
public void test_encryptWithAlgorithmParameters() throws Exception {
byte[] plaintext = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 , 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33 };
PBEKeySpec pbeKS = new PBEKeySpec("aaaaa".toCharArray());
int i = 0;
for (int keySize : KEY_SIZES) {
for (int shaVariant : SHA_VARIANTS) {
String algorithmName = "PBEWithHmacSHA" + shaVariant + "AndAES_" + keySize;
AlgorithmParameters ap = AlgorithmParameters.getInstance(algorithmName, "BC");
ap.init(TEST_PBE_PARAMETER_SPEC);
SecretKeyFactory skf = SecretKeyFactory.getInstance(
algorithmName, "BC");
Key key = skf.generateSecret(pbeKS);
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");
c.init(Cipher.ENCRYPT_MODE, key, ap);
byte[] encrypted = c.doFinal(plaintext);
assertEquals(
Arrays.toString(ENCRYPT_KNOWN_ANSWERS[i]),
Arrays.toString(encrypted));
c.init(Cipher.DECRYPT_MODE, key, ap);
byte[] decrypted = c.doFinal(encrypted);
assertEquals(
Arrays.toString(plaintext),
Arrays.toString(decrypted));
i++;
}
}
}
public void test_correctNames() throws Exception {
for (int keySize : KEY_SIZES) {
for (int shaVariant : SHA_VARIANTS) {
String algorithmName = "PBEWithHmacSHA" + shaVariant + "AndAES_" + keySize;
AlgorithmParameters ap = AlgorithmParameters.getInstance(algorithmName, "BC");
ap.init(TEST_PBE_PARAMETER_SPEC);
assertTrue(ap.toString().matches("(?i:.*hmacsha" + shaVariant + ".*)"));
assertTrue(ap.toString().matches("(?i:.*aes" + +keySize + ".*)"));
}
}
}
public void test_encryptWithNoSalt() throws Exception {
// Encrypting with no salt is allowed if using a PKCS5 scheme, which
// the SHA-based ones aren't but MD5-based ones are.
String algorithmName = "PBEwithMD5andDES";
SecretKeyFactory skf = SecretKeyFactory.getInstance(algorithmName, "BC");
Key key = skf.generateSecret(new PBEKeySpec("aaaaa".toCharArray()));
Cipher c = Cipher.getInstance(algorithmName, "BC");
c.init(Cipher.DECRYPT_MODE, key, new PBEParameterSpec(new byte[0], 1000));
}
}