I am using the following code for a my sampled 3DES encryption I am using:
package Algorithms;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
public class MyDES {
public static String encrypt(String pass,String plainText) throws NoSuchAlgorithmException, UnsupportedEncodingException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
byte[] key = pass.getBytes("UTF-8"); //get byte arrays of the given password
MessageDigest sha = MessageDigest.getInstance("SHA-1"); //get SHA-1 hashing instance
key=sha.digest(key); //has the given password
key=Arrays.copyOf(key,24);//take the first 16 bytes as the key for DES encryption
SecretKeySpec sks = new SecretKeySpec(key, "DESede");//key spec for 3-DES
Cipher c = Cipher.getInstance("DESede");//get an instance of 3DES
c.init(Cipher.ENCRYPT_MODE,sks); //initialize 3DES to encrypt mode with given parameters
byte[] cipherTextBytes = c.doFinal(plainText.getBytes()); //encrypt
System.out.println("key used: "+new String(key)+" cipher generated "+new String(cipherTextBytes));
StringBuffer cipherText= new StringBuffer();
for(int i=0;i<cipherTextBytes.length;i++)
{
cipherText.append(Integer.toHexString(cipherTextBytes[i]));
}
System.out.println("Final Cipher returned: "+cipherText.toString());
return cipherText.toString();
}
public static String decrypt(String pass,String cipherText) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
System.out.println("Initially in decryption-> pass:"+pass+" cipher: "+cipherText);
byte[] byteArray = new byte[cipherText.length() / 2];
int j=0;
for(int k=0;k<cipherText.length()-1;k+=2)
{
String o= cipherText.substring(k,k+2);
int dec = Integer.parseInt(o,16);
byteArray[j++] = (byte)dec;
}
String plainText="";
byte[] key = pass.getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key=sha.digest(key);
key=Arrays.copyOf(key,24);
System.out.println("\nkey obtained: "+new String(key)+"\n Later cipher text:-> "+new String(byteArray));
SecretKeySpec sks = new SecretKeySpec(key, "DESede");
Cipher c = Cipher.getInstance("DESede");
c.init(Cipher.DECRYPT_MODE,sks);
plainText = new String(c.doFinal(byteArray));
return plainText;
}
}
Here I am trying to take a password, hash it using SHA-1 and then use the generated has as a key to my 3DES. The generated cipher is being converted to hexadecimal representation as I having trouble saving and retrieving the strange characters in the cipher.
In decryption I am converting the cipher from hexadecimal to normal string again and then decrypting it. But I am getting a javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
Exception. Any idea where I am wrong?
Ah i think i got it. Try to simplify your code a bit, is hard to read. Avoid using strings and work as much as you can with arrays, when you have to work with binary data is better to use byte arrays.
Isolate the problems! Split your program in smaller functions that does simpler task.
You can use a standard Base64 encoder to do that. See http://www.docjar.com/docs/api/sun/misc/BASE64Encoder.html Base64 is of course shorter than hex encoding.
If you want to go on with the HEX conversion try to use these functions i found on google: http://www.developerfeed.com/javacore/blog/how-convert-hex-string-bytes-and-viceversa-java
I tried to simplify the code a little. Instead of new sun.misc.BASE64Encoder().encode() or decode() you can use the new encoding functions you are going to write.
private static byte[] getPassKey(String pass)
{
byte[] passKey = pass.getBytes("UTF-8"); //get byte arrays of the given password
byte[] shaKey = MessageDigest.getInstance("SHA-1").digest(passKey);
return Arrays.copyOf(shaKey,24);
}
public static String encrypt(String pass, String plainText) throws NoSuchAlgorithmException, UnsupportedEncodingException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
Cipher desCipher = Cipher.getInstance("DESede");
desCipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(getPassKey(pass), "DESede"));
byte[] cipherTextBytes = desCipher.doFinal(plainText.getBytes());
String encoded = new sun.misc.BASE64Encoder().encode(cipherTextBytes);
return encoded;
}
public static String decrypt(String pass,String cipherText) throws UnsupportedEncodingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
byte[] decoded = new sun.misc.BASE64Encoder().decode(cipherText);
Cipher desCipher = Cipher.getInstance("DESede");
desCipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(getPassKey(pass), "DESede"));
plainText = new String(desCipher.doFinal(decoded));
return plainText;
}
Not tested, just written by scratch in notepad.