Skip to content

Commit

Permalink
updated default DSA parameters to follow 186-4
Browse files Browse the repository at this point in the history
  • Loading branch information
dghgit committed Nov 3, 2016
1 parent f03bb05 commit 50a5306
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 3 deletions.
Expand Up @@ -6,18 +6,26 @@
import java.security.SecureRandom;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.DSAParameterSpec;
import java.util.Hashtable;

import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.generators.DSAKeyPairGenerator;
import org.bouncycastle.crypto.generators.DSAParametersGenerator;
import org.bouncycastle.crypto.params.DSAKeyGenerationParameters;
import org.bouncycastle.crypto.params.DSAParameterGenerationParameters;
import org.bouncycastle.crypto.params.DSAParameters;
import org.bouncycastle.crypto.params.DSAPrivateKeyParameters;
import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
import org.bouncycastle.util.Integers;
import org.bouncycastle.util.Properties;

public class KeyPairGeneratorSpi
extends java.security.KeyPairGenerator
{
private static Hashtable params = new Hashtable();
private static Object lock = new Object();

DSAKeyGenerationParameters param;
DSAKeyPairGenerator engine = new DSAKeyPairGenerator();
int strength = 1024;
Expand All @@ -41,6 +49,7 @@ public void initialize(

this.strength = strength;
this.random = random;
this.initialised = false;
}

public void initialize(
Expand All @@ -64,10 +73,65 @@ public KeyPair generateKeyPair()
{
if (!initialised)
{
DSAParametersGenerator pGen = new DSAParametersGenerator();
Integer paramStrength = Integers.valueOf(strength);

if (params.containsKey(paramStrength))
{
param = (DSAKeyGenerationParameters)params.get(paramStrength);
}
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 = (DSAKeyGenerationParameters)params.get(paramStrength);
}
else
{
DSAParametersGenerator pGen;
DSAParameterGenerationParameters dsaParams;

// Typical combination of keysize and size of q.
// keysize = 1024, q's size = 160
// keysize = 2048, q's size = 224
// keysize = 2048, q's size = 256
// keysize = 3072, q's size = 256
// For simplicity if keysize is greater than 1024 then we choose q's size to be 256.
// For legacy keysize that is less than 1024-bit, we just use the 186-2 style parameters
if (strength == 1024)
{
pGen = new DSAParametersGenerator();
if (Properties.isOverrideSet("org.bouncycastle.dsa.FIPS186-2for1024bits"))
{
pGen.init(strength, certainty, random);
}
else
{
dsaParams = new DSAParameterGenerationParameters(1024, 160, certainty, random);
pGen.init(dsaParams);
}
}
else if (strength > 1024)
{
dsaParams = new DSAParameterGenerationParameters(strength, 256, certainty, random);
pGen = new DSAParametersGenerator(new SHA256Digest());
pGen.init(dsaParams);
}
else
{
pGen = new DSAParametersGenerator();
pGen.init(strength, certainty, random);
}
param = new DSAKeyGenerationParameters(random, pGen.generateParameters());

params.put(paramStrength, param);
}
}
}

pGen.init(strength, certainty, random);
param = new DSAKeyGenerationParameters(random, pGen.generateParameters());
engine.init(param);
initialised = true;
}
Expand Down
47 changes: 47 additions & 0 deletions prov/src/test/java/org/bouncycastle/jce/provider/test/DSATest.java
Expand Up @@ -20,6 +20,7 @@
import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.spec.DSAParameterSpec;
Expand Down Expand Up @@ -1294,6 +1295,51 @@ private void testDSA2Parameters()
}
}

private void testKeyGeneration(int keysize)
throws Exception
{
KeyPairGenerator generator = KeyPairGenerator.getInstance("DSA", "BC");
generator.initialize(keysize);
KeyPair keyPair = generator.generateKeyPair();
DSAPrivateKey priv = (DSAPrivateKey)keyPair.getPrivate();
DSAParams params = priv.getParams();
isTrue("keysize mismatch", keysize == params.getP().bitLength());
// The NIST standard does not fully specify the size of q that
// must be used for a given key size. Hence there are differences.
// For example if keysize = 2048, then OpenSSL uses 256 bit q's by default,
// but the SUN provider uses 224 bits. Both are acceptable sizes.
// The tests below simply asserts that the size of q does not decrease the
// overall security of the DSA.
int qsize = params.getQ().bitLength();
switch (keysize)
{
case 1024:
isTrue("Invalid qsize for 1024 bit key:" + qsize, qsize >= 160);
break;
case 2048:
isTrue("Invalid qsize for 2048 bit key:" + qsize, qsize >= 224);
break;
case 3072:
isTrue("Invalid qsize for 3072 bit key:" + qsize, qsize >= 256);
break;
default:
fail("Invalid key size:" + keysize);
}
// Check the length of the private key.
// For example GPG4Browsers or the KJUR library derived from it use
// q.bitCount() instead of q.bitLength() to determine the size of the private key
// and hence would generate keys that are much too small.
isTrue("privkey error", priv.getX().bitLength() >= qsize - 32);
}

private void testKeyGenerationAll()
throws Exception
{
testKeyGeneration(1024);
testKeyGeneration(2048);
testKeyGeneration(3072);
}

public void performTest()
throws Exception
{
Expand Down Expand Up @@ -1331,6 +1377,7 @@ public void performTest()
testNullParameters();
testValidate();
testModified();
testKeyGenerationAll();
}

protected BigInteger[] derDecode(
Expand Down

0 comments on commit 50a5306

Please sign in to comment.