3DES CBC mode
843811Apr 17 2006 — edited Oct 25 2007My task to create a class that take 2 parameters 1)String Key, 2)String text then encrypt the string using the giving key and retrun the base64 encoding. My class seem working but the remote server did not decrypted.
one thing of the vendor specification is the IV should match \0\0\0\0\ (8 bytes of null) I think I did not know what to do there :)
here is the requirement:
1- use padding of type "[PKCS5] PKCS #5, Password-Based Encryption Standard" (see http://www.di-mgt.com.au/cryptopad.html). Microsoft .NET automatically pads the string as needed by default.
2- Encrypt the above resultant string using the Cipher Block Chaining (CBC) feedback mode of triple-DES encryption with an initial value for the feedback loop set to eight consecutive NUL (ASCII code 0) characters. The key to be used for this encryption is the key1. The cipher block chaining (CBC) feedback mode supports an additional, optional parameter named IV, which you'll need to implement as follows:
* The IV property contains the initial value which will be used to
start a cipher feedback mode; it will always be a string of exactly one block in length. After encrypting or decrypting a string, this value is updated to reflect the modified feedback text. The parameter is read-only, and cannot be assigned a new value.
* If the mode property is set to MODE_CBC or MODE_CFB, the IV property
must be provided and must be a string of the same length as the block size. Not providing a value for the IV property will result in a ValueError exception.
* The IV property must be an 8-byte string and its value must be:
'\0\0\0\0\0\0\0\0' (a string of eight NUL characters)
here is my code:
import javax.crypto.*;
import javax.crypto.spec.*;
import java.security.*;
import java.io.*;
import javax.crypto.spec.IvParameterSpec;
import java.security.spec.AlgorithmParameterSpec;
public class TDESStringEncryptor
{
// private static int BLOCK_SIZE = 8;
public static void main(String[] args)
{
try
{
TDESStringEncryptor enc = new TDESStringEncryptor();
String value = enc.Encrypt(args[0], args[1]);
System.err.println(value);
}
catch (Exception ex)
{
System.err.println(ex);
}
}
public String Encrypt(String inkey, String data)
throws Exception
{
//--------------------- start ----------------------------
//byte[] iv = new byte[]{(byte)0x8E, 0x12, 0x39, (byte)0x9C,0x07, 0x72, 0x6F, 0x5A};
byte [] iv = {0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40};
AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
// convert key to byte array and get it into a key object
byte[] rawkey = inkey.getBytes();
DESedeKeySpec keyspec = new DESedeKeySpec(rawkey);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
SecretKey key = keyfactory.generateSecret(keyspec);
Cipher c2 = Cipher.getInstance( "DESede/CBC/PKCS5Padding" );
//----------------start ---------------
c2.init(Cipher.ENCRYPT_MODE, key, paramSpec);
//c2.init( Cipher.ENCRYPT_MODE, key );
byte encodedParameters[] = c2.getParameters().getEncoded();
byte[] out = c2.doFinal(data.getBytes() );
/*
Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key);
//byte[] out = cipher.doFinal( padString(data).getBytes() );
byte[] out = cipher.doFinal(data.getBytes() );
*/
//String tst = byteArrayToHexString( out );
return new sun.misc.BASE64Encoder().encode(out);
//return byteArrayToHexString( out );
}
private String byteArrayToHexString(byte in[])
{
byte ch = 0x00;
int i = 0;
if ( in == null || in.length <= 0 )
return null;
String pseudo[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8",
"9", "A", "B", "C", "D", "E", "F"};
StringBuffer out = new StringBuffer( in.length * 2 );
while ( i < in.length )
{
ch = (byte) ( in[i] & 0xF0 );
ch = (byte) ( ch >>> 4 );
ch = (byte) ( ch & 0x0F );
out.append( pseudo[ (int) ch] );
ch = (byte) ( in[i] & 0x0F );
out.append( pseudo[ (int) ch] );
i++;
}
String rslt = new String( out );
return rslt;
}
}