sl@0: /* sl@0: * Copyright (c) 2006-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 uses the Bouncy Castle APIs PKCS#12 KDF to generate encryption keys + ivs sl@0: * and mac keys for use with compatibility testing. sl@0: * sl@0: */ sl@0: sl@0: sl@0: package com.symbian.security; sl@0: sl@0: import java.math.BigInteger; 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.CipherParameters; sl@0: import org.bouncycastle.crypto.params.KeyParameter; sl@0: import org.bouncycastle.crypto.params.ParametersWithIV; sl@0: sl@0: public class Pkcs12Pbe { sl@0: private PKCS12ParametersGenerator pgen; sl@0: sl@0: public Pkcs12Pbe() { sl@0: pgen = new PKCS12ParametersGenerator(new SHA1Digest()); sl@0: } sl@0: sl@0: public static void main(String args[]) { sl@0: try { sl@0: if (args.length < 5) { sl@0: usage(); sl@0: System.exit(-1); sl@0: sl@0: } sl@0: int keyLength = Integer.parseInt(args[0]); sl@0: int blockSize = Integer.parseInt(args[1]); sl@0: int iterations = Integer.parseInt(args[2]); sl@0: String salt = args[3]; sl@0: String password = args[4]; sl@0: byte[] saltBytes = hexToByteArray(salt); sl@0: sl@0: Pkcs12Pbe pbe = new Pkcs12Pbe(); sl@0: pbe.getKey(keyLength, blockSize, iterations, password, saltBytes); sl@0: } sl@0: catch (Exception e) { sl@0: System.exit(-1); sl@0: } sl@0: } sl@0: sl@0: private static byte[] hexToByteArray(String hex) throws Exception { sl@0: if (hex.length() % 2 != 0) { sl@0: throw new Exception("hexToByteArray: odd number of nibbles"); sl@0: } sl@0: StringBuffer hexBuffer = new StringBuffer(hex); sl@0: sl@0: byte[] byteBuffer = new byte[hexBuffer.length() / 2]; sl@0: for (int i = 0; i < hexBuffer.length(); i+=2) { sl@0: try { sl@0: byteBuffer[i / 2] = (byte) Integer.parseInt(hexBuffer.substring(i, i+2), 16); sl@0: } sl@0: catch (NumberFormatException e) { sl@0: System.err.println("hexToByteArray: invalid hex string: " + hex); sl@0: throw e; sl@0: } sl@0: } sl@0: return byteBuffer; sl@0: } sl@0: sl@0: private static void usage() { sl@0: System.err sl@0: .println("Usage: pkcs12pbe \n"); sl@0: } sl@0: sl@0: private void getKey(int keyLen, int ivLen, int iterCount, String password, sl@0: byte[] salt) { sl@0: System.out.print("key len = " + keyLen + ", iter count = " sl@0: + iterCount + ", password = \"" + password + "\", salt = "); sl@0: printUnformattedByteArray(salt); 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: CipherParameters cp = pgen.generateDerivedParameters(keyLen, ivLen); sl@0: sl@0: ParametersWithIV ivp = (ParametersWithIV) cp; sl@0: KeyParameter kp = (KeyParameter) ivp.getParameters(); sl@0: sl@0: System.out.print("key "); sl@0: printUnformattedByteArray((kp.getKey())); sl@0: System.out.print("iv "); sl@0: printUnformattedByteArray(ivp.getIV()); sl@0: sl@0: kp = (KeyParameter) pgen.generateDerivedMacParameters(160); sl@0: System.out.print("160bit hmac key "); sl@0: printUnformattedByteArray((kp.getKey())); sl@0: sl@0: } sl@0: sl@0: // unformatted hex strings that can be passed as arguments to openssl sl@0: private void printUnformattedByteArray(byte[] a) { sl@0: StringBuffer line = new StringBuffer(); sl@0: sl@0: for (int i = 0; i < a.length; i++) { sl@0: line.append(hexStr(a[i], 2)); sl@0: } sl@0: System.out.println(line); sl@0: } sl@0: sl@0: private String hexStr(int val, int width) { sl@0: StringBuffer result = new StringBuffer(); sl@0: while (--width >= 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: return result.toString(); sl@0: } sl@0: }