package org.bouncycastle.jcajce.provider.asymmetric.dh; import java.security.InvalidAlgorithmParameterException; import java.security.KeyPair; import java.security.SecureRandom; import java.security.spec.AlgorithmParameterSpec; import java.util.Hashtable; import javax.crypto.spec.DHParameterSpec; import org.bouncycastle.crypto.AsymmetricCipherKeyPair; import org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator; import org.bouncycastle.crypto.generators.DHParametersGenerator; import org.bouncycastle.crypto.params.DHKeyGenerationParameters; import org.bouncycastle.crypto.params.DHParameters; import org.bouncycastle.crypto.params.DHPrivateKeyParameters; import org.bouncycastle.crypto.params.DHPublicKeyParameters; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.util.Integers; public class KeyPairGeneratorSpi extends java.security.KeyPairGenerator { private static Hashtable params = new Hashtable(); private static Object lock = new Object(); DHKeyGenerationParameters param; DHBasicKeyPairGenerator engine = new DHBasicKeyPairGenerator(); int strength = 1024; int certainty = 20; SecureRandom random = new SecureRandom(); boolean initialised = false; public KeyPairGeneratorSpi() { super("DH"); } public void initialize( int strength, SecureRandom random) { this.strength = strength; this.random = random; } public void initialize( AlgorithmParameterSpec params, SecureRandom random) throws InvalidAlgorithmParameterException { if (!(params instanceof DHParameterSpec)) { throw new InvalidAlgorithmParameterException("parameter object not a DHParameterSpec"); } DHParameterSpec dhParams = (DHParameterSpec)params; param = new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL())); engine.init(param); initialised = true; } public KeyPair generateKeyPair() { if (!initialised) { Integer paramStrength = Integers.valueOf(strength); if (params.containsKey(paramStrength)) { param = (DHKeyGenerationParameters)params.get(paramStrength); } else { DHParameterSpec dhParams = BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(strength); if (dhParams != null) { param = new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL())); } else { synchronized (lock) { // we do the check again in case we were blocked by a generator for // our key size. if (params.containsKey(paramStrength)) { param = (DHKeyGenerationParameters)params.get(paramStrength); } else { DHParametersGenerator pGen = new DHParametersGenerator(); pGen.init(strength, certainty, random); param = new DHKeyGenerationParameters(random, pGen.generateParameters()); params.put(paramStrength, param); } } } } engine.init(param); initialised = true; } AsymmetricCipherKeyPair pair = engine.generateKeyPair(); DHPublicKeyParameters pub = (DHPublicKeyParameters)pair.getPublic(); DHPrivateKeyParameters priv = (DHPrivateKeyParameters)pair.getPrivate(); return new KeyPair(new BCDHPublicKey(pub), new BCDHPrivateKey(priv)); } }