0

I was surprised, that widely used in java world encryption mechanism does not work in my case.

Consider this code:

    for (Provider provider: Security.getProviders()) {
        System.out.println(provider.getName());
        for (String key: provider.stringPropertyNames())
            System.out.println("\t" + key + "\t" + provider.getProperty(key));
    }

Here is the output of interest:

Cipher.GOST28147    org.bouncycastle.jce.provider.JCEBlockCipher$GOST28147

And now the problem code:

import javax.crypto.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.security.Key;
import java.security.Provider;
import java.security.Security;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.util.encoders.Hex;

public class Main {

public static BouncyCastleProvider bc = new BouncyCastleProvider();

static {
    Security.addProvider(bc);
}

public static void main(String[] args) {
    byte[] data = "This is message, length=32 bytes".getBytes();

    Key key;
    CipherInputStream       cIn;
    CipherOutputStream      cOut;
    ByteArrayInputStream    bIn;
    ByteArrayOutputStream   bOut;
    byte[]                  bytes;

    byte[] keyData = Hex.decode("8182838485868788898a8b8c8d8e8f80d1d2d3d4d5d6d7d8d9dadbdcdddedfd0");

    key = new SecretKeySpec(keyData,"GOST28147");

    Cipher cipher = Cipher.getInstance("GOST28147/ECB/NoPadding", bc);

    cipher.init(Cipher.ENCRYPT_MODE, key); //Exception in thread "main" java.security.InvalidKeyException: Illegal key size or default parameters

    bOut = new ByteArrayOutputStream();

    cOut = new CipherOutputStream(bOut, cipher);

    for (int i = 0; i != data.length / 2; i++)
    {
        cOut.write(data[i]);
    }
    cOut.write(data, data.length / 2, data.length - data.length / 2);
    cOut.close();

    bytes = bOut.toByteArray();

    System.out.print(key.toString() + System.lineSeparator());
    System.out.print(byteArrayToString(bytes) + System.lineSeparator());
}
}

Full stacktrace is:

Exception in thread "main" java.security.InvalidKeyException: Illegal key size or default parameters
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1026)
    at javax.crypto.Cipher.init(Cipher.java:1245)
    at javax.crypto.Cipher.init(Cipher.java:1186)
    at com.test.Main.main(Main.java:45)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

ECB/NOPADDING here is just because of testing purposes - I know about it's weaknesses and have no plans to deploy it anywhere.

Also I've checked this question for possible solution but replacement of local_policy.jar and US_export_policy.jar did't solved the issue.

I'm using JDK 1.8. What have I missed that such a basic encryption tasks does not work for me?

There are several quite similar to mine issues here(1,2) but there is no suitable answer anywhere.

Community
  • 1
  • 1
im_infamous
  • 327
  • 1
  • 3
  • 17
  • So, did you check that the keysize is correct? – Kayaman Mar 17 '16 at 13:34
  • @Mr.M if the key is smaller than 32 bytes then there is `Exception in thread "main" java.security.InvalidKeyException: Key length invalid. Key needs to be 32 byte - 256 bit!!!` – im_infamous Mar 17 '16 at 13:39
  • @Kayaman even 32 byte key gives exception `Illegal key size or default parameters` – im_infamous Mar 17 '16 at 13:40
  • The stacktrace shows that the problem is in `Cipher.checkCryptoPerm`, which checks if you have export strength encryption available or not. You need to install the policy files (correctly) and it will work (or at least you'll get a different kind of error). – Kayaman Mar 17 '16 at 13:42
  • @Kayaman policies are intalled already: i.e. files in /lib/security was replaced for downloaded `.jar`'s. Maybe this is not how install is done or reboot/cache invalidation required? – im_infamous Mar 17 '16 at 13:45
  • 1
    No, there's no reboots or magic required. Did you install the files in `${JAVA_HOME}/jre/lib/security`? Double check. Then triple check. I just did this a while ago, and there's no problems when you install them to the correct directory. There are two `lib/security` directories, and if you install them in the wrong one, nothing will happen. – Kayaman Mar 17 '16 at 13:49
  • 1
    Thank you very much, Kayman, seems like I'm done. Issue was solved by placing these jars to `${JAVA_HOME}/jre/lib/security` **and** `${JAVA_HOME}/jdk/lib/security`. Also there was no `${JAVA_HOME}`, so I've set it - don't know if this influences in any way. – im_infamous Mar 17 '16 at 14:00
  • The `jdk/lib/security` one should be redundant, but I suppose it won't break anything either. – Kayaman Mar 17 '16 at 14:01

0 Answers0