66import java .security .SecureRandom ;
77import java .security .spec .AlgorithmParameterSpec ;
88import java .security .spec .DSAParameterSpec ;
9+ import java .util .Hashtable ;
910
1011import org .bouncycastle .crypto .AsymmetricCipherKeyPair ;
12+ import org .bouncycastle .crypto .digests .SHA256Digest ;
1113import org .bouncycastle .crypto .generators .DSAKeyPairGenerator ;
1214import org .bouncycastle .crypto .generators .DSAParametersGenerator ;
1315import org .bouncycastle .crypto .params .DSAKeyGenerationParameters ;
16+ import org .bouncycastle .crypto .params .DSAParameterGenerationParameters ;
1417import org .bouncycastle .crypto .params .DSAParameters ;
1518import org .bouncycastle .crypto .params .DSAPrivateKeyParameters ;
1619import org .bouncycastle .crypto .params .DSAPublicKeyParameters ;
20+ import org .bouncycastle .util .Integers ;
21+ import org .bouncycastle .util .Properties ;
1722
1823public class KeyPairGeneratorSpi
1924 extends java .security .KeyPairGenerator
2025{
26+ private static Hashtable params = new Hashtable ();
27+ private static Object lock = new Object ();
28+
2129 DSAKeyGenerationParameters param ;
2230 DSAKeyPairGenerator engine = new DSAKeyPairGenerator ();
2331 int strength = 1024 ;
@@ -41,6 +49,7 @@ public void initialize(
4149
4250 this .strength = strength ;
4351 this .random = random ;
52+ this .initialised = false ;
4453 }
4554
4655 public void initialize (
@@ -64,10 +73,65 @@ public KeyPair generateKeyPair()
6473 {
6574 if (!initialised )
6675 {
67- DSAParametersGenerator pGen = new DSAParametersGenerator ();
76+ Integer paramStrength = Integers .valueOf (strength );
77+
78+ if (params .containsKey (paramStrength ))
79+ {
80+ param = (DSAKeyGenerationParameters )params .get (paramStrength );
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 = (DSAKeyGenerationParameters )params .get (paramStrength );
91+ }
92+ else
93+ {
94+ DSAParametersGenerator pGen ;
95+ DSAParameterGenerationParameters dsaParams ;
96+
97+ // Typical combination of keysize and size of q.
98+ // keysize = 1024, q's size = 160
99+ // keysize = 2048, q's size = 224
100+ // keysize = 2048, q's size = 256
101+ // keysize = 3072, q's size = 256
102+ // For simplicity if keysize is greater than 1024 then we choose q's size to be 256.
103+ // For legacy keysize that is less than 1024-bit, we just use the 186-2 style parameters
104+ if (strength == 1024 )
105+ {
106+ pGen = new DSAParametersGenerator ();
107+ if (Properties .isOverrideSet ("org.bouncycastle.dsa.FIPS186-2for1024bits" ))
108+ {
109+ pGen .init (strength , certainty , random );
110+ }
111+ else
112+ {
113+ dsaParams = new DSAParameterGenerationParameters (1024 , 160 , certainty , random );
114+ pGen .init (dsaParams );
115+ }
116+ }
117+ else if (strength > 1024 )
118+ {
119+ dsaParams = new DSAParameterGenerationParameters (strength , 256 , certainty , random );
120+ pGen = new DSAParametersGenerator (new SHA256Digest ());
121+ pGen .init (dsaParams );
122+ }
123+ else
124+ {
125+ pGen = new DSAParametersGenerator ();
126+ pGen .init (strength , certainty , random );
127+ }
128+ param = new DSAKeyGenerationParameters (random , pGen .generateParameters ());
129+
130+ params .put (paramStrength , param );
131+ }
132+ }
133+ }
68134
69- pGen .init (strength , certainty , random );
70- param = new DSAKeyGenerationParameters (random , pGen .generateParameters ());
71135 engine .init (param );
72136 initialised = true ;
73137 }
0 commit comments