0

Hey guys after trying out stuff for about an hour I am stuck. I just wanted to try out encryption in java and got stumped with many error messages I just don't understand. After looking up in the javadocs how long the key needs to be for AES, it says 56, I naturally thought it means I have to have 56 bits, so a 7 long byte array. But it doesn't seem to work. Here is the stack trace:

java.security.InvalidKeyException: Invalid key length: 7 bytes null
    at com.sun.crypto.provider.DESCipher.engineGetKeySize(DESCipher.java:373)
    at javax.crypto.Cipher.passCryptoPermCheck(Cipher.java:1067)
    at javax.crypto.Cipher.checkCryptoPerm(Cipher.java:1038)
    at javax.crypto.Cipher.implInit(Cipher.java:805)
    at javax.crypto.Cipher.chooseProvider(Cipher.java:864)
    at javax.crypto.Cipher.init(Cipher.java:1396)
    at javax.crypto.Cipher.init(Cipher.java:1327)
    at com.skrelpoid.secure.Crypt.encrypt(Crypt.java:34)
    at com.skrelpoid.secure.Crypt.main(Crypt.java:95)
Exception in thread "main" java.lang.NullPointerException
    at com.skrelpoid.secure.Crypt.decrypt(Crypt.java:47)
    at com.skrelpoid.secure.Crypt.main(Crypt.java:97)`

And here is my code:

import java.security.NoSuchAlgorithmException;
import java.util.Random;

import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

// adapted from http://stackoverflow.com/a/1205272/
public class Crypt {
    private static byte[] ivBytes;
    private static Cipher cipher;
    private static SecretKeySpec keySpec;
    private static IvParameterSpec ivSpec;
    private static Random random;
    private static long seed;

    private Crypt() {
    }

    private static byte[] ivBytes() {
        random.setSeed(seed);
        byte[] bytes = new byte[7];
        random.nextBytes(bytes);
        return bytes;
    }

    public static String encrypt(String key, String input) {
        prepare(key);
        byte[] inputBytes = input.getBytes();
        try {
            cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
            byte[] encrypted = new byte[cipher.getOutputSize(inputBytes.length)];
            int enc_len = cipher.update(inputBytes, 0, inputBytes.length, encrypted, 0);
            enc_len += cipher.doFinal(encrypted, enc_len);
            return new String(encrypted);
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public static String decrypt(String key, String input) {
        prepare(key);
        byte[] inputBytes = input.getBytes();
        try {
            cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
            byte[] decrypted = new byte[cipher.getOutputSize(inputBytes.length)];
            int dec_len = cipher.update(inputBytes, 0, inputBytes.length, decrypted, 0);
            dec_len += cipher.doFinal(decrypted, dec_len);
            return new String(decrypted);
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    private static void prepare(String key) {
        byte[] keyBytes = new byte[7];
        byte[] bytesFromKey = key.getBytes();
        int length = keyBytes.length < bytesFromKey.length ? keyBytes.length : bytesFromKey.length;
        System.arraycopy(bytesFromKey, 0, keyBytes, 0, length);
        // if the length is smaller then keyBytes length, there are trailing
        // zeros in the keyBytes. Fill them with the use of the seed;
        if (length < keyBytes.length) {
            random.setSeed(seed);
            byte[] newBytes = new byte[keyBytes.length - length];
            random.nextBytes(newBytes);
            System.arraycopy(newBytes, 0, keyBytes, length, newBytes.length);
        }

        keySpec = new SecretKeySpec(keyBytes, "DES");
        ivSpec = new IvParameterSpec(ivBytes);
        try {
            cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (NoSuchPaddingException e) {
            e.printStackTrace();
        }
    }

    public static void init(String id) {
        seed = id.hashCode();
        random = new Random(seed);
        ivBytes = ivBytes();
    }

    public static final void main(String[] args) {
        init("123456");
        String str = "ILikeTurtles";
        String key = "KEY123";
        String encrypted = encrypt(key, str);
        System.out.println(encrypted);
        System.out.println(decrypt(key, encrypted));
    }
}

I would really appreciate if someone could help me get that code to work. Thanks in advance

Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
Skrelp
  • 181
  • 2
  • 16
  • AES and DES are different encryption algorithms with different key sizes. DES has a 56-bit key in 8 bytes, AES supports three key sizes: 128, 192 & 256 bits in 16, 24 & 32 bytes respectively. DES is no longer considered secure and should not be used in new work. DES has been superseded by AES, use AES. – zaph Jan 15 '17 at 11:51

1 Answers1

3

DES requires 8 byte keys and an 8 byte IV.

Jonathan Rosenne
  • 2,159
  • 17
  • 27
  • I really wonder how i should have known that. After all, the javadoc says the length needs to be 56. Anyway thanks. – Skrelp Jan 14 '17 at 23:41
  • 1
    It is 56 meaningful bits plus 8 parity bits, total 64 bits = 8 bytes. The 4 trailing bytes mean you have a bug. – Jonathan Rosenne Jan 14 '17 at 23:50
  • Historically the lsb of each byte was parity, these days, almost without exception, it is ignored. – zaph Jan 15 '17 at 00:13
  • To be exact DES requires 56+8bit=8byte key and DES-*CBC* requires 1block=8byte IV, as do most other JCE-supported modes, but ECB requires no IV and some DES modes elsewhere have used other sizes. Note ciphertext for DES, like other modern-era algorithms, is effectively random bits and should be handled as binary; converting to `String` and back the way you do will frequently result in losing most or all of your data. Using a predictable RNG like Java `Random` for CBC IV in general leads to vulnerabilities, but here it doesn't matter since DES is already insecure for nearly 2 decades. – dave_thompson_085 Jan 15 '17 at 01:42