7

I tried the following methods to generate a DSA private (and public) key with a 2048-bit key length:

Via keytool

keytool -genkeypair -alias MyKeyPair -keyalg DSA -keysize 2048 -validity 365 -keystore MyKeyStore.ks

Resulting in:

keytool error: java.lang.IllegalArgumentException: Modulus size must range from 512 to 1024 and be a multiple of 64

Via code

KeyPairGenerator keyGen = KeyPairGenerator.getInstance(keyAlgorithm,"BC");
keyGen.initialize(numBits);

Resulting in:

Exception in thread "main" java.security.InvalidParameterException: strength must be from 512 - 1024 and a multiple of 64
    at org.bouncycastle.jcajce.provider.asymmetric.dsa.KeyPairGeneratorSpi.initialize(Unknown Source)
    at java.security.KeyPairGenerator.initialize(KeyPairGenerator.java:340)

Above example uses Bouncy Castle's implementation because somewhere I read it should support 2048-bit DSA keys. I also tried the default one with the same error.

I installed the (JCE) Unlimited Strength Jurisdiction Policy Files. According to this output, you would expect large keys should be possible:

System.out.println("DSA Max key length: " + Cipher.getMaxAllowedKeyLength("DSA"));
DSA Max key length: 2147483647

But if you echeck the Keysize Restrictions in the JCE Providers Docs, 1024-bit is the max.

Who can tell if 2048 bit private key simply not supported in Java 7? Or if there is another way to create a key of this size and import it into a Java Keystore?

The Java 8 API gives away it will support bigger keys. So we might need to wait until next year.

Clouren
  • 372
  • 1
  • 3
  • 10

3 Answers3

2

Java 8 fixes this: http://docs.oracle.com/javase/8/docs/technotes/guides/security/enhancements-8.html "SUN provider: Support for 2048-bit DSA key pair generation and additional signature algorithms for 2048-bit DSA keys such as SHA224withDSA and SHA256withDSA."

Paul Crowley
  • 1,656
  • 1
  • 14
  • 26
  • 1
    I just tried keytool -genkeypair -alias MyKeyPair -keyalg DSA -keysize 2048 -validity 365 -keystore MyKeyStore.ks using jdk1.8.0_31 and I got: "java.security.InvalidKeyException: Key is too long for this algorithm" – Ya. May 23 '15 at 17:57
1

Because the maximum length of key allowed is 1024bits. you getting an exception "Modulus size must be between 512..1024.." which means Key Size. You can download the JCE with Unlimited Jurisdiction Policy files for your Java version (7 or 8) from oracle's link: Oracle's official site. But you should know that 1024 bits is enough for digital signature algorithms.

Community
  • 1
  • 1
M.Veli
  • 519
  • 1
  • 6
  • 15
  • 1
    1024 bits is *not* enough for digital signature algorithms.Bruce Schneier was telling people using that short a key to "wake up" in 2007 - it is long past time to move on to stronger keys. https://www.schneier.com/blog/archives/2007/05/307digit_number.html (NB this only applies to RSA, DSA DH and the like which are vulnerable to NFS - other algorithms like ECDSA can use much shorter keys.) – Paul Crowley Sep 11 '14 at 10:29
  • @PaulCrowley isn't Bruce talking about RSA in particular when referring to 1024 bits, i.e. not DSA? – Pimin Konstantin Kefaloukos Sep 16 '14 at 09:00
  • RSA and DSA are pretty much the same strength for the same key length, since NFS works on both of them, as I say above. – Paul Crowley Jul 10 '16 at 16:02
0

I have been through this before and all I have to say is this sucks man. Here are your basic choices if you want a higher key-size.

  1. Go here and download the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy File - You have to install this on each machine that uses the code.

  2. Write your own implementation from scratch.

  3. Give up & eat a cookie :P (I choose this one)


Now let me explain your problem. Java had the fantastic idea of limiting cryptography in countries where it has limits or is illegal. That file undoes what limits on the crypto systems Java set.

Hope that helps. Also don't forget you can check to see if someone has the file on their system. All you do is something like this:

boolean isUnlimitedSupported = false;
try {
    KeyGenerator kgen = KeyGenerator.getInstance("AES", "SunJCE");
    kgen.init(256);
    isUnlimitedSupported = true;
} catch (NoSuchAlgorithmException e) {
    isUnlimitedSupported = false;
} catch (NoSuchProviderException e) {
    isUnlimitedSupported = false;
}
System.out.println("isUnlimitedSupported = " + isUnlimitedSupported);

You might find this helpful: http://docs.oracle.com/javase/1.4.2/docs/guide/security/jce/JCERefGuide.html#AppD

Zeveso
  • 1,274
  • 3
  • 21
  • 41
  • Thanks for your reaction. I'm aware of the JCE Unlimited Strength Jurisdiction Policy. As I explained, I already installed it. However, it hasn't removed the 1024-bit limit of the KeyPairGenerator. It seems the KeyPairGenerator itself has a hard limit of 1024 instead of leaving this limit to the specific implementation like Bounty Castle. So point 1 is not the full solution. Point 2 is not a path one would like or should take I think. It might be the only choice, but I would expect there are other workarounds (around JCE for example). For now I choose point 3 and stick to 1024-bit. – Clouren Oct 01 '13 at 06:07
  • @Clouren Would you be willing to take the source code from Bounty Castle and manually change it in order to work? Source is here: http://www.bouncycastle.org/latest_releases.html - I just looked over it. It is possible. I would start in the 'bcprov-jdk15on-149\src.zip\org\bouncycastle\crypto\engines' area once you get the source code. – Zeveso Oct 03 '13 at 18:10