6
6
import java .security .SecureRandom ;
7
7
import java .security .spec .AlgorithmParameterSpec ;
8
8
import java .security .spec .DSAParameterSpec ;
9
+ import java .util .Hashtable ;
9
10
10
11
import org .bouncycastle .crypto .AsymmetricCipherKeyPair ;
12
+ import org .bouncycastle .crypto .digests .SHA256Digest ;
11
13
import org .bouncycastle .crypto .generators .DSAKeyPairGenerator ;
12
14
import org .bouncycastle .crypto .generators .DSAParametersGenerator ;
13
15
import org .bouncycastle .crypto .params .DSAKeyGenerationParameters ;
16
+ import org .bouncycastle .crypto .params .DSAParameterGenerationParameters ;
14
17
import org .bouncycastle .crypto .params .DSAParameters ;
15
18
import org .bouncycastle .crypto .params .DSAPrivateKeyParameters ;
16
19
import org .bouncycastle .crypto .params .DSAPublicKeyParameters ;
20
+ import org .bouncycastle .util .Integers ;
21
+ import org .bouncycastle .util .Properties ;
17
22
18
23
public class KeyPairGeneratorSpi
19
24
extends java .security .KeyPairGenerator
20
25
{
26
+ private static Hashtable params = new Hashtable ();
27
+ private static Object lock = new Object ();
28
+
21
29
DSAKeyGenerationParameters param ;
22
30
DSAKeyPairGenerator engine = new DSAKeyPairGenerator ();
23
31
int strength = 1024 ;
@@ -41,6 +49,7 @@ public void initialize(
41
49
42
50
this .strength = strength ;
43
51
this .random = random ;
52
+ this .initialised = false ;
44
53
}
45
54
46
55
public void initialize (
@@ -64,10 +73,65 @@ public KeyPair generateKeyPair()
64
73
{
65
74
if (!initialised )
66
75
{
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
+ }
68
134
69
- pGen .init (strength , certainty , random );
70
- param = new DSAKeyGenerationParameters (random , pGen .generateParameters ());
71
135
engine .init (param );
72
136
initialised = true ;
73
137
}
0 commit comments