crypto/weakcryptospi/source/pkcs12kdf/Pkcs12Pbe.java
changeset 19 cd501b96611d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/crypto/weakcryptospi/source/pkcs12kdf/Pkcs12Pbe.java	Fri Nov 06 13:21:00 2009 +0200
@@ -0,0 +1,130 @@
+/*
+* Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+* This program uses the Bouncy Castle APIs PKCS#12 KDF to generate encryption keys + ivs 
+* and mac keys for use with compatibility testing.
+*
+*/
+
+
+package com.symbian.security;
+
+import java.math.BigInteger;
+import java.security.SecureRandom;
+import org.bouncycastle.crypto.PBEParametersGenerator;
+import org.bouncycastle.crypto.digests.SHA1Digest;
+import org.bouncycastle.crypto.generators.PKCS12ParametersGenerator;
+import org.bouncycastle.crypto.CipherParameters;
+import org.bouncycastle.crypto.params.KeyParameter;
+import org.bouncycastle.crypto.params.ParametersWithIV;
+
+public class Pkcs12Pbe {
+	private PKCS12ParametersGenerator pgen;
+
+	public Pkcs12Pbe() {
+		pgen = new PKCS12ParametersGenerator(new SHA1Digest());
+	}
+
+	public static void main(String args[]) {
+		try {
+			if (args.length < 5) {
+				usage();
+				System.exit(-1);
+				
+			}
+			int keyLength = Integer.parseInt(args[0]);
+			int blockSize = Integer.parseInt(args[1]);
+			int iterations = Integer.parseInt(args[2]);
+			String salt = args[3];
+			String password = args[4];		
+			byte[] saltBytes = hexToByteArray(salt);
+	
+			Pkcs12Pbe pbe = new Pkcs12Pbe();
+			pbe.getKey(keyLength, blockSize, iterations, password, saltBytes);			
+		}
+		catch (Exception e) {
+			System.exit(-1);
+		}
+	}
+	
+	private static byte[] hexToByteArray(String hex) throws Exception {
+		if (hex.length() % 2 != 0) {
+			throw new Exception("hexToByteArray: odd number of nibbles");
+		}
+		StringBuffer hexBuffer = new StringBuffer(hex);
+		
+		byte[] byteBuffer = new byte[hexBuffer.length() / 2];
+		for (int i = 0; i < hexBuffer.length(); i+=2) {
+			try {
+				byteBuffer[i / 2] = (byte) Integer.parseInt(hexBuffer.substring(i, i+2), 16);
+			}
+			catch (NumberFormatException e) {
+				System.err.println("hexToByteArray: invalid hex string: " + hex);
+				throw e;
+			}
+		}
+		return byteBuffer;
+	}
+
+	private static void usage() {
+		System.err
+				.println("Usage: pkcs12pbe <key length> <block_size> <iterations> <salt> <password>\n");
+	}
+	
+	private void getKey(int keyLen, int ivLen, int iterCount, String password,
+			byte[] salt) {
+		System.out.print("key len = " + keyLen + ", iter count = "
+				+ iterCount + ", password = \"" + password + "\", salt = ");		
+		printUnformattedByteArray(salt);
+
+		char[] pwChars = password.toCharArray();
+		byte[] pwBytes = PBEParametersGenerator.PKCS12PasswordToBytes(pwChars);
+
+		pgen.init(pwBytes, salt, iterCount);
+		CipherParameters cp = pgen.generateDerivedParameters(keyLen, ivLen);
+
+		ParametersWithIV ivp = (ParametersWithIV) cp;
+		KeyParameter kp = (KeyParameter) ivp.getParameters();
+
+		System.out.print("key ");
+		printUnformattedByteArray((kp.getKey()));
+		System.out.print("iv ");
+		printUnformattedByteArray(ivp.getIV());
+
+		kp = (KeyParameter) pgen.generateDerivedMacParameters(160);
+		System.out.print("160bit hmac key ");
+		printUnformattedByteArray((kp.getKey()));
+
+	}
+
+	// unformatted hex strings that can be passed as arguments to openssl
+	private void printUnformattedByteArray(byte[] a) {
+		StringBuffer line = new StringBuffer();
+		
+		for (int i = 0; i < a.length; i++) {
+			line.append(hexStr(a[i], 2));
+		}
+		System.out.println(line);
+	}	
+
+	private String hexStr(int val, int width) {
+		StringBuffer result = new StringBuffer();
+		while (--width >= 0) {
+			int bitPos = 4 * width;
+			int nybble = (val & (0xf << bitPos)) >> bitPos;
+			result.append(Integer.toHexString(nybble));
+		}
+		return result.toString();
+	}
+}