sl@0: /* sl@0: * Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: * All rights reserved. sl@0: * This component and the accompanying materials are made available sl@0: * under the terms of the License "Eclipse Public License v1.0" sl@0: * which accompanies this distribution, and is available sl@0: * at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: * sl@0: * Initial Contributors: sl@0: * Nokia Corporation - initial contribution. sl@0: * sl@0: * Contributors: sl@0: * sl@0: * Description: sl@0: * This program generates keys with Bouncy Castle for compatibility testing. sl@0: * sl@0: */ sl@0: sl@0: sl@0: import java.security.SecureRandom; sl@0: import org.bouncycastle.crypto.PBEParametersGenerator; sl@0: import org.bouncycastle.crypto.digests.SHA1Digest; sl@0: import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator; sl@0: import org.bouncycastle.crypto.params.KeyParameter; sl@0: sl@0: public class GenTestDKs sl@0: { sl@0: public static void main(String[] args) sl@0: { sl@0: PKCS12ParametersGenerator pgen = new PKCS12ParametersGenerator(new SHA1Digest()); sl@0: sl@0: // SB.4: key lengths for defined OIDs sl@0: // (168 for triple DES will first exercise chaining.) sl@0: final int[] keyLens = {40, 128, 168, 368}; sl@0: sl@0: // SB.4 iteration count is recommended to be 1024 or more sl@0: final int[] iterCounts = {1, 2, 4, 8, 128, 1024, 1536, 2048}; sl@0: sl@0: // SB.4 salt should be same length as hash function output sl@0: // (=160 bits for SHA1.) sl@0: byte[][] salts = new byte[3][]; sl@0: salts[0] = new byte[] {'S', 'A', 'L', 'T'}; sl@0: System.out.println("4 byte salt"); sl@0: printByteArray(salts[0]); sl@0: sl@0: // calls to nextBytes() are only executed once sl@0: /* SecureRandom sr; sl@0: try { sr = SecureRandom.getInstance("SHA1PRNG", "SUN"); } sl@0: catch (Exception e) sl@0: { sl@0: System.err.println("UNABLE TO GET RANDOM SOURCE"); sl@0: return; sl@0: } sl@0: */ sl@0: // salts[1] = new byte[160 / 8]; sl@0: // sr.nextBytes(salts[1]); sl@0: salts[1] = new byte[] sl@0: { sl@0: (byte) 0x1d, (byte) 0x56, (byte) 0x50, (byte) 0x78, sl@0: (byte) 0xc3, (byte) 0x50, (byte) 0x6f, (byte) 0x89, sl@0: (byte) 0xbd, (byte) 0xa7, (byte) 0x3b, (byte) 0xb6, sl@0: (byte) 0xe3, (byte) 0xe5, (byte) 0xb8, (byte) 0xa3, sl@0: (byte) 0x68, (byte) 0x3d, (byte) 0xd3, (byte) 0x62 sl@0: }; sl@0: System.out.println("20 byte salt (same size as SHA1 output)"); sl@0: printByteArray(salts[1]); sl@0: sl@0: // salts[2] = new byte[200 / 8]; sl@0: // sr.nextBytes(salts[2]); sl@0: salts[2] = new byte[] sl@0: { sl@0: (byte) 0xe2, (byte) 0x2c, (byte) 0x7b, (byte) 0x03, sl@0: (byte) 0x16, (byte) 0x3a, (byte) 0xe5, (byte) 0x47, sl@0: (byte) 0xf8, (byte) 0x23, (byte) 0x9d, (byte) 0xa4, sl@0: (byte) 0x0d, (byte) 0x6f, (byte) 0x46, (byte) 0xd7, sl@0: (byte) 0x9e, (byte) 0xa3, (byte) 0xc6, (byte) 0xff, sl@0: (byte) 0xb3, (byte) 0xf0, (byte) 0x4e, (byte) 0xbe, sl@0: (byte) 0x61 sl@0: }; sl@0: System.out.println("25 byte salt"); sl@0: printByteArray(salts[2]); sl@0: sl@0: final String passwds[] = {"0000", "0001", "PSWD", "password", "abcdefghijklmnopqrstuvwxyz"}; sl@0: sl@0: for (int keyLenIdx = 0; keyLenIdx < keyLens.length; ++keyLenIdx) sl@0: { sl@0: for (int iterIdx = 0; iterIdx < iterCounts.length; ++iterIdx) sl@0: { sl@0: for (int saltIdx = 0; saltIdx < salts.length; ++saltIdx) sl@0: { sl@0: for (int pwdIdx = 0; pwdIdx < passwds.length; ++pwdIdx) sl@0: { sl@0: testKey(pgen, keyLens[keyLenIdx], iterCounts[iterIdx], passwds[pwdIdx], salts[saltIdx]); sl@0: } // for (int pwdIdx = 0; pwdIdx < passwds.length; ++pwdIdx) sl@0: } // for (int saltIdx = 0; saltIdx < salts.length; ++saltIdx) sl@0: } // for (int iterIdx = 0; iterIdx < iterCounts.length; ++iterIdx) sl@0: } // for (int keyLenIdx = 0; keyLenIdx < keyLens.length; ++keyLenIdx) sl@0: } sl@0: sl@0: private static void testKey( sl@0: PKCS12ParametersGenerator pgen, sl@0: int keyLen, int iterCount, String password, byte[] salt) sl@0: { sl@0: System.out.println( sl@0: "key len = " + keyLen + ", iter count = " + iterCount sl@0: + ", password = \"" + password + "\", salt len = " + salt.length); sl@0: sl@0: char[] pwChars = password.toCharArray(); sl@0: byte[] pwBytes = PBEParametersGenerator.PKCS12PasswordToBytes(pwChars); sl@0: sl@0: pgen.init(pwBytes, salt, iterCount); sl@0: KeyParameter kp = (KeyParameter) pgen.generateDerivedParameters(keyLen); sl@0: printByteArray(kp.getKey()); sl@0: } sl@0: sl@0: private static void printByteArray(byte[] a) sl@0: { sl@0: final int BLOCK_SIZE = 16; sl@0: int keyLen = a.length; sl@0: int rowCount = keyLen / BLOCK_SIZE; sl@0: if ((keyLen % BLOCK_SIZE) != 0) sl@0: ++rowCount; sl@0: sl@0: for (int row = 0; row < rowCount; ++row) sl@0: { sl@0: int start = row * BLOCK_SIZE; sl@0: int end = Math.min(start + BLOCK_SIZE, keyLen); sl@0: sl@0: StringBuffer line = new StringBuffer("[" + hexStr(start, 4) + "]"); sl@0: sl@0: for (int i = start; i < end; ++i) sl@0: line.append(" " + hexStr(a[i], 2)); sl@0: System.out.println(line); sl@0: } sl@0: System.out.println(); sl@0: } sl@0: sl@0: private static String hexStr(int val, int width) sl@0: { sl@0: StringBuffer result = new StringBuffer(); sl@0: while (--width >= 0) sl@0: { sl@0: int bitPos = 4 * width; sl@0: int nybble = (val & (0xf << bitPos)) >> bitPos; sl@0: result.append(Integer.toHexString(nybble)); sl@0: } sl@0: sl@0: return result.toString(); sl@0: } sl@0: }