|
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 } |