1915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom/*
2915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom * Copyright (C) 2010 The Android Open Source Project
3915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom *
4915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom * Licensed under the Apache License, Version 2.0 (the "License");
5915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom * you may not use this file except in compliance with the License.
6915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom * You may obtain a copy of the License at
7915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom *
8915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom *      http://www.apache.org/licenses/LICENSE-2.0
9915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom *
10915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom * Unless required by applicable law or agreed to in writing, software
11915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom * distributed under the License is distributed on an "AS IS" BASIS,
12915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom * See the License for the specific language governing permissions and
14915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom * limitations under the License.
15915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom */
16915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
17915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrompackage libcore.javax.crypto;
18915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
19915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstromimport java.security.spec.InvalidKeySpecException;
20915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstromimport java.security.spec.KeySpec;
21915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstromimport java.util.Arrays;
22915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstromimport javax.crypto.SecretKey;
23915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstromimport javax.crypto.SecretKeyFactory;
24915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstromimport javax.crypto.spec.PBEKeySpec;
25915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstromimport junit.framework.TestCase;
263f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luhimport libcore.java.security.StandardNames;
27915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
28915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrompublic class SecretKeyFactoryTest extends TestCase {
29915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
30915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    private static final char[] PASSWORD = "google".toCharArray();
31915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    /**
32915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     * Salts should be random to reduce effectiveness of dictionary
33915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     * attacks, but need not be kept secret from attackers. For more
34915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     * information, see http://en.wikipedia.org/wiki/Salt_(cryptography)
35915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     */
36915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    private static final byte[] SALT = {0, 1, 2, 3, 4, 5, 6, 7};
37915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    /**
38915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     * The number of iterations should be higher for production
39915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     * strength protection. The tolerable value may vary from device
40915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     * to device, but 8192 should be acceptable for PBKDF2 on a Nexus One.
41915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     */
42915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    private static final int ITERATIONS = 1024;
43915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    private static final int KEY_LENGTH = 128;
44915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
45915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    public void test_PBKDF2_required_parameters() throws Exception {
46915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
47915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
48915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        // PBEKeySpec validates arguments most to be non-null, non-empty, postive, etc.
49915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        // Focus on insufficient PBEKeySpecs
50915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
51915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        // PBEKeySpecs password only constructor
52915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        try {
53915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            KeySpec ks = new PBEKeySpec(null);
54915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            factory.generateSecret(ks);
55915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            fail();
56915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        } catch (InvalidKeySpecException expected) {
57915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        }
58915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        try {
59915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            KeySpec ks = new PBEKeySpec(new char[0]);
60915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            factory.generateSecret(ks);
61915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            fail();
62915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        } catch (InvalidKeySpecException expected) {
63915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        }
64915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        try {
65915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            KeySpec ks = new PBEKeySpec(PASSWORD);
66915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            factory.generateSecret(ks);
67915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            fail();
68915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        } catch (InvalidKeySpecException expected) {
69915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        }
70915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
71915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
72915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        // PBEKeySpecs constructor without key length
73915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        try {
74915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            KeySpec ks = new PBEKeySpec(null, SALT, ITERATIONS);
75915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            factory.generateSecret(ks);
76915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            fail();
77915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        } catch (InvalidKeySpecException expected) {
78915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        }
79915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        try {
80915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            KeySpec ks = new PBEKeySpec(new char[0], SALT, ITERATIONS);
81915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            factory.generateSecret(ks);
82915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            fail();
83915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        } catch (InvalidKeySpecException expected) {
84915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        }
85915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        try {
86915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            KeySpec ks = new PBEKeySpec(PASSWORD, SALT, ITERATIONS);
87915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            factory.generateSecret(ks);
88915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            fail();
89915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        } catch (InvalidKeySpecException expected) {
90915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        }
91915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
92915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        try {
93915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            KeySpec ks = new PBEKeySpec(null, SALT, ITERATIONS, KEY_LENGTH);
94915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            factory.generateSecret(ks);
95915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            fail();
96915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        } catch (IllegalArgumentException expected) {
97915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        }
98915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
99915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        try {
100915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            KeySpec ks = new PBEKeySpec(new char[0], SALT, ITERATIONS, KEY_LENGTH);
101915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            factory.generateSecret(ks);
102915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            fail();
103915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        } catch (IllegalArgumentException expected) {
104915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        }
105915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
106915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        KeySpec ks = new PBEKeySpec(PASSWORD, SALT, ITERATIONS, KEY_LENGTH);
107915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        factory.generateSecret(ks);
108915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    }
109915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
110915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    public void test_PBKDF2_b3059950() throws Exception {
1113f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        byte[] expected = new byte[] {
112915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom                        (byte)0x70, (byte)0x74, (byte)0xdb, (byte)0x72,
113915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom                        (byte)0x35, (byte)0xd4, (byte)0x11, (byte)0x68,
114915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom                        (byte)0x83, (byte)0x7c, (byte)0x14, (byte)0x1f,
115915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom                        (byte)0xf6, (byte)0x4a, (byte)0xb0, (byte)0x54
1163f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh                    };
1173f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        test_PBKDF2_UTF8(PASSWORD, SALT, ITERATIONS, KEY_LENGTH, expected);
1183f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        test_PBKDF2_8BIT(PASSWORD, SALT, ITERATIONS, KEY_LENGTH, expected);
119915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    }
120915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
121915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    /**
122915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     * 64-bit Test vector from RFC 3211
123915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     *
124915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     * See also org.bouncycastle.crypto.test.PKCS5Test
125915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     */
126915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    public void test_PBKDF2_rfc3211_64() throws Exception {
127915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        char[] password = "password".toCharArray();
128915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        byte[] salt = new byte[] {
129915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            (byte)0x12, (byte)0x34, (byte)0x56, (byte)0x78,
130915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            (byte)0x78, (byte)0x56, (byte)0x34, (byte)0x12
131915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        };
132915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        int iterations = 5;
133915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        int keyLength = 64;
134915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        byte[] expected = new byte[] {
135915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            (byte)0xD1, (byte)0xDA, (byte)0xA7, (byte)0x86,
136915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            (byte)0x15, (byte)0xF2, (byte)0x87, (byte)0xE6
137915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        };
1383f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        test_PBKDF2_UTF8(password, salt, iterations, keyLength, expected);
1393f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        test_PBKDF2_8BIT(password, salt, iterations, keyLength, expected);
140915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    }
141915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
142915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    /**
143915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     * 192-bit Test vector from RFC 3211
144915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     *
145915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     * See also org.bouncycastle.crypto.test.PKCS5Test
146915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom     */
147915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    public void test_PBKDF2_rfc3211_192() throws Exception {
148915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        char[] password = ("All n-entities must communicate with other "
149915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom                           + "n-entities via n-1 entiteeheehees").toCharArray();
150915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        byte[] salt = new byte[] {
151915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            (byte)0x12, (byte)0x34, (byte)0x56, (byte)0x78,
152915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            (byte)0x78, (byte)0x56, (byte)0x34, (byte)0x12
153915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        };
154915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        int iterations = 500;
155915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        int keyLength = 192;
156915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        byte[] expected = new byte[] {
157915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            (byte)0x6a, (byte)0x89, (byte)0x70, (byte)0xbf, (byte)0x68, (byte)0xc9,
158915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            (byte)0x2c, (byte)0xae, (byte)0xa8, (byte)0x4a, (byte)0x8d, (byte)0xf2,
159915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            (byte)0x85, (byte)0x10, (byte)0x85, (byte)0x86, (byte)0x07, (byte)0x12,
160915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom            (byte)0x63, (byte)0x80, (byte)0xcc, (byte)0x47, (byte)0xab, (byte)0x2d
161915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        };
1623f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        test_PBKDF2_UTF8(password, salt, iterations, keyLength, expected);
1633f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        test_PBKDF2_8BIT(password, salt, iterations, keyLength, expected);
1643f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh    }
1653f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh
1663f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh   /**
1673f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh    * Unicode Test vector for b/8312059.
1683f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh    *
1693f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh    * See also https://code.google.com/p/android/issues/detail?id=40578
1703f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh    */
1713f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh    public void test_PBKDF2_b8312059() throws Exception {
1723f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh
1733f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        char[] password = "\u0141\u0142".toCharArray();
1743f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        byte[] salt = "salt".getBytes();
1753f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        int iterations = 4096;
1763f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        int keyLength = 160;
1773f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        byte[] expected_utf8 = new byte[] {
1783f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh            (byte)0x4c, (byte)0xe0, (byte)0x6a, (byte)0xb8, (byte)0x48, (byte)0x04,
1793f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh            (byte)0xb7, (byte)0xe7, (byte)0x72, (byte)0xf2, (byte)0xaf, (byte)0x5e,
1803f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh            (byte)0x54, (byte)0xe9, (byte)0x03, (byte)0xad, (byte)0x59, (byte)0x64,
1813f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh            (byte)0x8b, (byte)0xab
1823f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        };
1833f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        byte[] expected_8bit = new byte[] {
1843f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh            (byte)0x6e, (byte)0x43, (byte)0xe0, (byte)0x18, (byte)0xc5, (byte)0x50,
1853f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh            (byte)0x0d, (byte)0xa7, (byte)0xfe, (byte)0x7a, (byte)0x44, (byte)0x4d,
1863f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh            (byte)0x99, (byte)0x5d, (byte)0x8c, (byte)0xae, (byte)0xc1, (byte)0xc9,
1873f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh            (byte)0x17, (byte)0xce
1883f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        };
1893f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        test_PBKDF2_UTF8(password, salt, iterations, keyLength, expected_utf8);
1903f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        test_PBKDF2_8BIT(password, salt, iterations, keyLength, expected_8bit);
1913f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh    }
1923f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh
1933f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh    private void test_PBKDF2_8BIT(char[] password, byte[] salt, int iterations, int keyLength,
1943f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh                                  byte[] expected) throws Exception {
1953f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        if (!StandardNames.IS_RI) {
1963f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh            SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1And8bit");
1973f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh            KeySpec ks = new PBEKeySpec(password, salt, iterations, keyLength);
1983f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh            SecretKey key = factory.generateSecret(ks);
1993f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh            assertTrue(Arrays.equals(expected, key.getEncoded()));
2003f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh        }
2013f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh
202915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    }
203915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
2043f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh    private void test_PBKDF2_UTF8(char[] password, byte[] salt, int iterations, int keyLength,
2053f410d3b2d68c77a2a84629b47c29226c235f57dWilliam Luh                                  byte[] expected) throws Exception {
206915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
207915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        KeySpec ks = new PBEKeySpec(password, salt, iterations, keyLength);
208915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        SecretKey key = factory.generateSecret(ks);
209915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom        assertTrue(Arrays.equals(expected, key.getEncoded()));
210915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom
211915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom    }
212915789995fc136049c13c8b0354e2f7009b653e4Brian Carlstrom}
213