InvalidKeyException: Invalid key size

Before marking this as a duplicate, read the complete question.

I reviewed countless questions here about this issue, and each answer said to install JCE. However, if I want to send the program to someone else, to another computer, practically anything from the development computer, they must also install JCE.

Is there a way to use smaller keys without having to install anything?

My encryption method;

public static String encrypt(String in) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException { String out = " "; // generate a key KeyGenerator keygen = KeyGenerator.getInstance("AES"); keygen.init(128); byte[] key = keygen.generateKey().getEncoded(); SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); // build the initialization vector SecureRandom random = new SecureRandom(); byte iv[] = new byte[16]; //generate random 16 byte IV. AES is always 16bytes random.nextBytes(iv); IvParameterSpec ivspec = new IvParameterSpec(iv); saveKey(key, iv); //<-- save to file // initialize the cipher for encrypt mode Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivspec); byte[] encrypted = cipher.doFinal(in.getBytes()); out = asHex(encrypted); return out; } 

And my decryption method:

 public static String decrypt(String in) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException, KeyFileNotFoundException, UnknownKeyException { String out = " "; byte[] key = readKey("key").clone(); //<--from file SecretKeySpec skeySpec = new SecretKeySpec(key, "AES"); byte[] iv = readKey("iv"); //<-- from file IvParameterSpec ivspec = new IvParameterSpec(iv); //initialize the cipher for decryption Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivspec); // decrypt the message byte[] decrypted = cipher.doFinal(in.getBytes()); out = asHex(decrypted); return out; } 

My saveKey () method:

 private static void saveKey(byte[] key, byte[] iv) throws FileNotFoundException, IOException { File keyFile = new File(Logging.getCurrentDir() + "\\cikey.key"); keys.setProperty("key", asHex(key)); keys.setProperty("iv", asHex(iv)); keys.store(new FileOutputStream(keyFile.getAbsolutePath(), false), null); } 

My readKey () method:

  private static byte[] readKey(String request) throws KeyFileNotFoundException, UnknownKeyException, FileNotFoundException, IOException { File keyFile = new File(Logging.getCurrentDir() + "\\cikey.key"); byte[] storage; keys.load(new FileInputStream(keyFile)); if (!keyFile.exists()) throw new KeyFileNotFoundException("Key file not located."); if (keys.containsKey(request) == false) throw new UnknownKeyException("Key not found."); else storage = keys.getProperty(request).getBytes(); return storage; } 

asHex () (transferring an array to String):

 public static String asHex(byte buf[]) { StringBuilder strbuf = new StringBuilder(buf.length * 2); for (int i = 0; i < buf.length; i++) { if (((int) buf[i] & 0xff) < 0x10) strbuf.append("0"); strbuf.append(Long.toString((int) buf[i] & 0xff, 16)); } return strbuf.toString(); } 
+4
source share
1 answer

Is there a way to use smaller keys without having to install anything?

You cannot use AES with key sizes smaller than 128 bits, but there are other ciphers available: DES, Blowfish, etc. They are not as secure as AES, but they can still do the trick if your application (like most applications) is not worth the hack. Here is an example for a 56 bit DES:

  public static String encrypt(String in) throws Exception { String out = " "; // generate a key KeyGenerator keygen = KeyGenerator.getInstance("DES"); keygen.init(56); byte[] key = keygen.generateKey().getEncoded(); SecretKeySpec skeySpec = new SecretKeySpec(key, "DES"); // build the initialization vector SecureRandom random = new SecureRandom(); byte iv[] = new byte[8]; //generate random 8 byte IV. random.nextBytes(iv); IvParameterSpec ivspec = new IvParameterSpec(iv); // initialize the cipher for encrypt mode Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivspec); byte[] encrypted = cipher.doFinal(in.getBytes()); out = asHex(encrypted); return out; } 

There is also a problem with storing and reading keys in code. You store them as hexadecimal, but consider them characters from the default platform encoding. Here is an example of how to make both operations homogeneous:

 private static void saveKey(byte[] key, byte[] iv) throws IOException { File keyFile = new File("C:/cikey.key"); keys.setProperty("key", toHexString(key)); keys.setProperty("iv", toHexString(iv)); keys.store(new FileOutputStream(keyFile.getAbsolutePath(), false), null); } private static byte[] readKey(String request) throws IOException { File keyFile = new File("C:/cikey.key"); keys.load(new FileInputStream(keyFile)); return toByteArray(keys.getProperty(request)); } public static String toHexString(byte[] array) { return DatatypeConverter.printHexBinary(array); } public static byte[] toByteArray(String s) { return DatatypeConverter.parseHexBinary(s); } 
+3
source

Source: https://habr.com/ru/post/1499707/


All Articles