19
|
1 |
/*
|
|
2 |
* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
|
|
3 |
* All rights reserved.
|
|
4 |
* This component and the accompanying materials are made available
|
|
5 |
* under the terms of the License "Eclipse Public License v1.0"
|
|
6 |
* which accompanies this distribution, and is available
|
|
7 |
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
|
|
8 |
*
|
|
9 |
* Initial Contributors:
|
|
10 |
* Nokia Corporation - initial contribution.
|
|
11 |
*
|
|
12 |
* Contributors:
|
|
13 |
*
|
|
14 |
* Description:
|
|
15 |
* This program uses the Bouncy Castle APIs PKCS#12 KDF to generate encryption keys + ivs
|
|
16 |
* and mac keys for use with compatibility testing.
|
|
17 |
*
|
|
18 |
*/
|
|
19 |
|
|
20 |
|
|
21 |
package com.symbian.security;
|
|
22 |
|
|
23 |
import java.math.BigInteger;
|
|
24 |
import java.security.SecureRandom;
|
|
25 |
import org.bouncycastle.crypto.PBEParametersGenerator;
|
|
26 |
import org.bouncycastle.crypto.digests.SHA1Digest;
|
|
27 |
import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
|
|
28 |
import org.bouncycastle.crypto.CipherParameters;
|
|
29 |
import org.bouncycastle.crypto.params.KeyParameter;
|
|
30 |
import org.bouncycastle.crypto.params.ParametersWithIV;
|
|
31 |
|
|
32 |
public class Pkcs12Pbe {
|
|
33 |
private PKCS12ParametersGenerator pgen;
|
|
34 |
|
|
35 |
public Pkcs12Pbe() {
|
|
36 |
pgen = new PKCS12ParametersGenerator(new SHA1Digest());
|
|
37 |
}
|
|
38 |
|
|
39 |
public static void main(String args[]) {
|
|
40 |
try {
|
|
41 |
if (args.length < 5) {
|
|
42 |
usage();
|
|
43 |
System.exit(-1);
|
|
44 |
|
|
45 |
}
|
|
46 |
int keyLength = Integer.parseInt(args[0]);
|
|
47 |
int blockSize = Integer.parseInt(args[1]);
|
|
48 |
int iterations = Integer.parseInt(args[2]);
|
|
49 |
String salt = args[3];
|
|
50 |
String password = args[4];
|
|
51 |
byte[] saltBytes = hexToByteArray(salt);
|
|
52 |
|
|
53 |
Pkcs12Pbe pbe = new Pkcs12Pbe();
|
|
54 |
pbe.getKey(keyLength, blockSize, iterations, password, saltBytes);
|
|
55 |
}
|
|
56 |
catch (Exception e) {
|
|
57 |
System.exit(-1);
|
|
58 |
}
|
|
59 |
}
|
|
60 |
|
|
61 |
private static byte[] hexToByteArray(String hex) throws Exception {
|
|
62 |
if (hex.length() % 2 != 0) {
|
|
63 |
throw new Exception("hexToByteArray: odd number of nibbles");
|
|
64 |
}
|
|
65 |
StringBuffer hexBuffer = new StringBuffer(hex);
|
|
66 |
|
|
67 |
byte[] byteBuffer = new byte[hexBuffer.length() / 2];
|
|
68 |
for (int i = 0; i < hexBuffer.length(); i+=2) {
|
|
69 |
try {
|
|
70 |
byteBuffer[i / 2] = (byte) Integer.parseInt(hexBuffer.substring(i, i+2), 16);
|
|
71 |
}
|
|
72 |
catch (NumberFormatException e) {
|
|
73 |
System.err.println("hexToByteArray: invalid hex string: " + hex);
|
|
74 |
throw e;
|
|
75 |
}
|
|
76 |
}
|
|
77 |
return byteBuffer;
|
|
78 |
}
|
|
79 |
|
|
80 |
private static void usage() {
|
|
81 |
System.err
|
|
82 |
.println("Usage: pkcs12pbe <key length> <block_size> <iterations> <salt> <password>\n");
|
|
83 |
}
|
|
84 |
|
|
85 |
private void getKey(int keyLen, int ivLen, int iterCount, String password,
|
|
86 |
byte[] salt) {
|
|
87 |
System.out.print("key len = " + keyLen + ", iter count = "
|
|
88 |
+ iterCount + ", password = \"" + password + "\", salt = ");
|
|
89 |
printUnformattedByteArray(salt);
|
|
90 |
|
|
91 |
char[] pwChars = password.toCharArray();
|
|
92 |
byte[] pwBytes = PBEParametersGenerator.PKCS12PasswordToBytes(pwChars);
|
|
93 |
|
|
94 |
pgen.init(pwBytes, salt, iterCount);
|
|
95 |
CipherParameters cp = pgen.generateDerivedParameters(keyLen, ivLen);
|
|
96 |
|
|
97 |
ParametersWithIV ivp = (ParametersWithIV) cp;
|
|
98 |
KeyParameter kp = (KeyParameter) ivp.getParameters();
|
|
99 |
|
|
100 |
System.out.print("key ");
|
|
101 |
printUnformattedByteArray((kp.getKey()));
|
|
102 |
System.out.print("iv ");
|
|
103 |
printUnformattedByteArray(ivp.getIV());
|
|
104 |
|
|
105 |
kp = (KeyParameter) pgen.generateDerivedMacParameters(160);
|
|
106 |
System.out.print("160bit hmac key ");
|
|
107 |
printUnformattedByteArray((kp.getKey()));
|
|
108 |
|
|
109 |
}
|
|
110 |
|
|
111 |
// unformatted hex strings that can be passed as arguments to openssl
|
|
112 |
private void printUnformattedByteArray(byte[] a) {
|
|
113 |
StringBuffer line = new StringBuffer();
|
|
114 |
|
|
115 |
for (int i = 0; i < a.length; i++) {
|
|
116 |
line.append(hexStr(a[i], 2));
|
|
117 |
}
|
|
118 |
System.out.println(line);
|
|
119 |
}
|
|
120 |
|
|
121 |
private String hexStr(int val, int width) {
|
|
122 |
StringBuffer result = new StringBuffer();
|
|
123 |
while (--width >= 0) {
|
|
124 |
int bitPos = 4 * width;
|
|
125 |
int nybble = (val & (0xf << bitPos)) >> bitPos;
|
|
126 |
result.append(Integer.toHexString(nybble));
|
|
127 |
}
|
|
128 |
return result.toString();
|
|
129 |
}
|
|
130 |
}
|