Skip to content

Commit 50a5306

Browse files
committed
updated default DSA parameters to follow 186-4
1 parent f03bb05 commit 50a5306

File tree

2 files changed

+114
-3
lines changed

2 files changed

+114
-3
lines changed

Diff for: prov/src/main/java/org/bouncycastle/jcajce/provider/asymmetric/dsa/KeyPairGeneratorSpi.java

+67-3
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,26 @@
66
import java.security.SecureRandom;
77
import java.security.spec.AlgorithmParameterSpec;
88
import java.security.spec.DSAParameterSpec;
9+
import java.util.Hashtable;
910

1011
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
12+
import org.bouncycastle.crypto.digests.SHA256Digest;
1113
import org.bouncycastle.crypto.generators.DSAKeyPairGenerator;
1214
import org.bouncycastle.crypto.generators.DSAParametersGenerator;
1315
import org.bouncycastle.crypto.params.DSAKeyGenerationParameters;
16+
import org.bouncycastle.crypto.params.DSAParameterGenerationParameters;
1417
import org.bouncycastle.crypto.params.DSAParameters;
1518
import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
1619
import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
20+
import org.bouncycastle.util.Integers;
21+
import org.bouncycastle.util.Properties;
1722

1823
public 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
}

Diff for: prov/src/test/java/org/bouncycastle/jce/provider/test/DSATest.java

+47
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.security.Security;
2121
import java.security.Signature;
2222
import java.security.SignatureException;
23+
import java.security.interfaces.DSAParams;
2324
import java.security.interfaces.DSAPrivateKey;
2425
import java.security.interfaces.DSAPublicKey;
2526
import java.security.spec.DSAParameterSpec;
@@ -1294,6 +1295,51 @@ private void testDSA2Parameters()
12941295
}
12951296
}
12961297

1298+
private void testKeyGeneration(int keysize)
1299+
throws Exception
1300+
{
1301+
KeyPairGenerator generator = KeyPairGenerator.getInstance("DSA", "BC");
1302+
generator.initialize(keysize);
1303+
KeyPair keyPair = generator.generateKeyPair();
1304+
DSAPrivateKey priv = (DSAPrivateKey)keyPair.getPrivate();
1305+
DSAParams params = priv.getParams();
1306+
isTrue("keysize mismatch", keysize == params.getP().bitLength());
1307+
// The NIST standard does not fully specify the size of q that
1308+
// must be used for a given key size. Hence there are differences.
1309+
// For example if keysize = 2048, then OpenSSL uses 256 bit q's by default,
1310+
// but the SUN provider uses 224 bits. Both are acceptable sizes.
1311+
// The tests below simply asserts that the size of q does not decrease the
1312+
// overall security of the DSA.
1313+
int qsize = params.getQ().bitLength();
1314+
switch (keysize)
1315+
{
1316+
case 1024:
1317+
isTrue("Invalid qsize for 1024 bit key:" + qsize, qsize >= 160);
1318+
break;
1319+
case 2048:
1320+
isTrue("Invalid qsize for 2048 bit key:" + qsize, qsize >= 224);
1321+
break;
1322+
case 3072:
1323+
isTrue("Invalid qsize for 3072 bit key:" + qsize, qsize >= 256);
1324+
break;
1325+
default:
1326+
fail("Invalid key size:" + keysize);
1327+
}
1328+
// Check the length of the private key.
1329+
// For example GPG4Browsers or the KJUR library derived from it use
1330+
// q.bitCount() instead of q.bitLength() to determine the size of the private key
1331+
// and hence would generate keys that are much too small.
1332+
isTrue("privkey error", priv.getX().bitLength() >= qsize - 32);
1333+
}
1334+
1335+
private void testKeyGenerationAll()
1336+
throws Exception
1337+
{
1338+
testKeyGeneration(1024);
1339+
testKeyGeneration(2048);
1340+
testKeyGeneration(3072);
1341+
}
1342+
12971343
public void performTest()
12981344
throws Exception
12991345
{
@@ -1331,6 +1377,7 @@ public void performTest()
13311377
testNullParameters();
13321378
testValidate();
13331379
testModified();
1380+
testKeyGenerationAll();
13341381
}
13351382

13361383
protected BigInteger[] derDecode(

0 commit comments

Comments
 (0)