1b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampackage org.bouncycastle.crypto;
2b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
3c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstromimport org.bouncycastle.util.Strings;
4c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
5b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam/**
6b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam * super class for all Password Based Encryption (PBE) parameter generator classes.
7b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam */
8b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallampublic abstract class PBEParametersGenerator
9b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam{
10b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    protected byte[]  password;
11b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    protected byte[]  salt;
12b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    protected int     iterationCount;
13b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
14b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
15b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * base constructor.
16b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
17b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    protected PBEParametersGenerator()
18b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
19b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
20b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
21b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
22b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * initialise the PBE generator.
23b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
24b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param password the password converted into bytes (see below).
25b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param salt the salt to be mixed with the password.
26b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param iterationCount the number of iterations the "mixing" function
27b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * is to be applied for.
28b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
29b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public void init(
30b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  password,
31b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        byte[]  salt,
32b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        int     iterationCount)
33b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
34b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.password = password;
35b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.salt = salt;
36b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        this.iterationCount = iterationCount;
37b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
38b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
39b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
40b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return the password byte array.
41b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
42b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return the password byte array.
43b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
44b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public byte[] getPassword()
45b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
46b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return password;
47b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
48b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
49b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
50b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return the salt byte array.
51b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
52b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return the salt byte array.
53b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
54b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public byte[] getSalt()
55b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
56b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return salt;
57b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
58b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
59b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
60b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * return the iteration count.
61b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
62b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return the iteration count.
63b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
64b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public int getIterationCount()
65b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
66b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        return iterationCount;
67b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
68b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
69b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
70b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * generate derived parameters for a key of length keySize.
71b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
72b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param keySize the length, in bits, of the key required.
73b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return a parameters object representing a key.
74b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
75b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public abstract CipherParameters generateDerivedParameters(int keySize);
76b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
77b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
78b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * generate derived parameters for a key of length keySize, and
79b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * an initialisation vector (IV) of length ivSize.
80b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
81b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param keySize the length, in bits, of the key required.
82b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param ivSize the length, in bits, of the iv required.
83b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return a parameters object representing a key and an IV.
84b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
85b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public abstract CipherParameters generateDerivedParameters(int keySize, int ivSize);
86b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
87b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
88b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * generate derived parameters for a key of length keySize, specifically
89b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * for use with a MAC.
90b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
91b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @param keySize the length, in bits, of the key required.
92b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return a parameters object representing a key.
93b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
94b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public abstract CipherParameters generateDerivedMacParameters(int keySize);
95b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
96b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
97b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * converts a password to a byte array according to the scheme in
98b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * PKCS5 (ascii, no padding)
99b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
1004c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @param password a character array representing the password.
101b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return a byte array representing the password.
102b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
103b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static byte[] PKCS5PasswordToBytes(
104b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        char[]  password)
105b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
106e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom        if (password != null)
107e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom        {
108e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom            byte[]  bytes = new byte[password.length];
109b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
110e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom            for (int i = 0; i != bytes.length; i++)
111e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom            {
112e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom                bytes[i] = (byte)password[i];
113e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom            }
114e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom
115e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom            return bytes;
116e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom        }
117e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom        else
118b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
119e1142c149e244797ce73b0e7fad40816e447a817Brian Carlstrom            return new byte[0];
120b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
121b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
122b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
123b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    /**
124b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * converts a password to a byte array according to the scheme in
125c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * PKCS5 (UTF-8, no padding)
126b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     *
1274c111300c39cb2e27f07fc2ae3b00e23ed4443b2Brian Carlstrom     * @param password a character array representing the password.
128b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     * @return a byte array representing the password.
129b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam     */
130c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    public static byte[] PKCS5PasswordToUTF8Bytes(
131c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom        char[]  password)
132c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    {
133a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        if (password != null)
134a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        {
135a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom            return Strings.toUTF8ByteArray(password);
136a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        }
137a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        else
138a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        {
139a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom            return new byte[0];
140a198e1ecc615e26a167d0f2dca9fa7e5fc62de10Brian Carlstrom        }
141c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    }
142c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom
143c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom    /**
144c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * converts a password to a byte array according to the scheme in
145c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * PKCS12 (unicode, big endian, 2 zero pad bytes at the end).
146c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     *
147c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @param password a character array representing the password.
148c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     * @return a byte array representing the password.
149c37f4a04ef89e73a39a59f3c5a179af8c8ab5974Brian Carlstrom     */
150b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    public static byte[] PKCS12PasswordToBytes(
151b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        char[]  password)
152b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    {
153b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        if (password != null && password.length > 0)
154b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
155b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                                       // +1 for extra 2 pad bytes.
156b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            byte[]  bytes = new byte[(password.length + 1) * 2];
157b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
158b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            for (int i = 0; i != password.length; i ++)
159b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            {
160b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                bytes[i * 2] = (byte)(password[i] >>> 8);
161b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam                bytes[i * 2 + 1] = (byte)password[i];
162b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            }
163b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam
164b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return bytes;
165b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
166b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        else
167b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        {
168b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam            return new byte[0];
169b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam        }
170b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam    }
171b61a96e7ef1a78acf013bbf08fe537e5b5f129caPeter Hallam}
172