Triple DES decryption invalid key with 16 bytes

纵饮孤独 提交于 2019-11-30 10:39:23

DES would expect an 8 byte key (with parity). So Triple DES expects a 24 byte key (with parity). Since you only have a 16 byte key, you have to replicate some of it, to get the final key. Oftentimes the first and last 8 bytes are the same. You can try two variants:

byte[] tdesKey = new byte[24];
System.arraycopy(hexConvert, 0, tdesKey, 0, 16);
System.arraycopy(hexConvert, 0, tdesKey, 16, 8);
// tdesKey := K1 || K2 || K1

or

byte[] tdesKey = new byte[24];
System.arraycopy(hexConvert, 8, tdesKey, 0, 8);
System.arraycopy(hexConvert, 0, tdesKey, 8, 16);
// tdesKey := K2 || K1 || K2

when

hexConvert := K1 || K2

Maybe you must to use this cipher:

public byte[] encTripleDes (String txt, byte [] key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidKeySpecException{
    DESedeKeySpec keySpec = new DESedeKeySpec(key);
    SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
    SecretKey ky = keyfactory.generateSecret(keySpec);

    Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, ky);
    return cipher.doFinal(txt.getBytes("UTF-8"));

}

And for decrypting:

public byte[] uncTripleDes (byte [] encryptedTextBytes, byte [] key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidKeySpecException{
    DESedeKeySpec keySpec = new DESedeKeySpec(key);
    SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
    SecretKey ky = keyfactory.generateSecret(keySpec);

    Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, ky);
    return cipher.doFinal(encryptedTextBytes);

}

Look that I use a "PKCS5Padding" in the instance of the cipher.

Notice that the padding is used for give the same size at all the blocks (for example if the last block is 788 instead of 1024).

For create the key, in my solution (it's not the only one), I calculate a sha-256 hash and then I get the necessary bytes for the Des key:

Calculating the hash:

public byte[] sumCalc (){ 
    String key = "anyKey";
    byte[] hashedKey = null;
    try {
        byte [] byteKey = key.getBytes("UTF-8");
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        hashedKey = md.digest(byteKey);
    }catch (Exception ex){
        System.err.println("Error generant clau" + ex);  
    }
    return hashedKey;
}

Finally get only the 128 bytes that we need for the Des key:

bytedKey = Arrays.copyOf(bytedKey, 16 ); // 16 use only first 128 bit. if 32 use only 256

It's my solution but not the only one!

You instantiate your Cipher as a (singel) DES Cipher with:

desCipher = Cipher.getInstance("DES/ECB/NoPadding");

But your key is a 16 byte 3Des key, and thuse you get the error

DES key too long - should be 8 bytes

Try instantiating your cipher as a 3DES cipher with:

desCipher = Cipher.getInstance("DESede/ECB/NoPadding");
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!