1package org.bouncycastle.jcajce.provider.asymmetric.dh; 2 3import java.security.InvalidAlgorithmParameterException; 4import java.security.KeyPair; 5import java.security.SecureRandom; 6import java.security.spec.AlgorithmParameterSpec; 7import java.util.Hashtable; 8 9import javax.crypto.spec.DHParameterSpec; 10 11import org.bouncycastle.crypto.AsymmetricCipherKeyPair; 12import org.bouncycastle.crypto.generators.DHBasicKeyPairGenerator; 13import org.bouncycastle.crypto.generators.DHParametersGenerator; 14import org.bouncycastle.crypto.params.DHKeyGenerationParameters; 15import org.bouncycastle.crypto.params.DHParameters; 16import org.bouncycastle.crypto.params.DHPrivateKeyParameters; 17import org.bouncycastle.crypto.params.DHPublicKeyParameters; 18import org.bouncycastle.jce.provider.BouncyCastleProvider; 19import org.bouncycastle.util.Integers; 20 21public class KeyPairGeneratorSpi 22 extends java.security.KeyPairGenerator 23{ 24 private static Hashtable params = new Hashtable(); 25 private static Object lock = new Object(); 26 27 DHKeyGenerationParameters param; 28 DHBasicKeyPairGenerator engine = new DHBasicKeyPairGenerator(); 29 int strength = 1024; 30 int certainty = 20; 31 SecureRandom random = new SecureRandom(); 32 boolean initialised = false; 33 34 public KeyPairGeneratorSpi() 35 { 36 super("DH"); 37 } 38 39 public void initialize( 40 int strength, 41 SecureRandom random) 42 { 43 this.strength = strength; 44 this.random = random; 45 } 46 47 public void initialize( 48 AlgorithmParameterSpec params, 49 SecureRandom random) 50 throws InvalidAlgorithmParameterException 51 { 52 if (!(params instanceof DHParameterSpec)) 53 { 54 throw new InvalidAlgorithmParameterException("parameter object not a DHParameterSpec"); 55 } 56 DHParameterSpec dhParams = (DHParameterSpec)params; 57 58 param = new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL())); 59 60 engine.init(param); 61 initialised = true; 62 } 63 64 public KeyPair generateKeyPair() 65 { 66 if (!initialised) 67 { 68 Integer paramStrength = Integers.valueOf(strength); 69 70 if (params.containsKey(paramStrength)) 71 { 72 param = (DHKeyGenerationParameters)params.get(paramStrength); 73 } 74 else 75 { 76 DHParameterSpec dhParams = BouncyCastleProvider.CONFIGURATION.getDHDefaultParameters(strength); 77 78 if (dhParams != null) 79 { 80 param = new DHKeyGenerationParameters(random, new DHParameters(dhParams.getP(), dhParams.getG(), null, dhParams.getL())); 81 } 82 else 83 { 84 synchronized (lock) 85 { 86 // we do the check again in case we were blocked by a generator for 87 // our key size. 88 if (params.containsKey(paramStrength)) 89 { 90 param = (DHKeyGenerationParameters)params.get(paramStrength); 91 } 92 else 93 { 94 95 DHParametersGenerator pGen = new DHParametersGenerator(); 96 97 pGen.init(strength, certainty, random); 98 99 param = new DHKeyGenerationParameters(random, pGen.generateParameters()); 100 101 params.put(paramStrength, param); 102 } 103 } 104 } 105 } 106 107 engine.init(param); 108 109 initialised = true; 110 } 111 112 AsymmetricCipherKeyPair pair = engine.generateKeyPair(); 113 DHPublicKeyParameters pub = (DHPublicKeyParameters)pair.getPublic(); 114 DHPrivateKeyParameters priv = (DHPrivateKeyParameters)pair.getPrivate(); 115 116 return new KeyPair(new BCDHPublicKey(pub), 117 new BCDHPrivateKey(priv)); 118 } 119} 120