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.