I'm encrypt data using triple DES. It works fine, but I have a question.
Where can I see the initialization vector (IV)?
It's 3des encyption with BASE64Decoder.
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class Crypter {
Cipher ecipher;
Cipher dcipher;
Crypter(String as_Phrase)
throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException {
this.ecipher = Cipher.getInstance("DESede");
this.dcipher = Cipher.getInstance("DESede");
this.ecipher.init(1, getSecretKey(as_Phrase));
this.dcipher.init(2, getSecretKey(as_Phrase));
}
public String encrypt(String as_valueToEncrypt)
throws BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException, IOException {
byte[] lbarr_utf8 = as_valueToEncrypt.getBytes("UTF8");
byte[] lbarr_enc = this.ecipher.doFinal(lbarr_utf8);
return new BASE64Encoder().encode(lbarr_enc);
}
public String decrypt(String as_valueToDecrypt)
throws BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException, IOException {
byte[] lbarr_enc = new BASE64Decoder().decodeBuffer(as_valueToDecrypt);
byte[] lbarr_utf8 = this.dcipher.doFinal(lbarr_enc);
return new String(lbarr_utf8, "UTF8");
}
private SecretKey getSecretKey(String as_Phrase)
throws UnsupportedEncodingException {
return new SecretKeySpec(as_Phrase.getBytes("UTF8"), "DESede");
}
}
You can get the IV from the cipher:
The problem is that the IV is generated during
init. Since youinitin the constructor you would run into the problem of using the same IV for every encryption of different ciphertexts. It's always best to generate a newCipherand init it for every encryption and decryption operation separately.You use the
DESedecipher which is actuallyDESede/ECB/PKCS5Padding. Note that the mode is ECB which doesn't use an IV. So the above call returnsnull. Although this is the default mode, it is not recommended. It's safer to useDESede/CBC/PKCS5Paddingwhich actually uses an IV.So when you decrypt in CBC mode you need to pass that IV in:
To reduce the burden of passing the IV around you could then append the IV to the front of the ciphertext before encoding it and slice it off before decrypting the ciphertext. DES is a 64-bit cipher so your IV will be 8 bytes long.