• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2006
  • Last Modified:

3DES CBC to encrypt data

Hello Experts, I am new to Java crypto. My task is 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 give wrong out pu, therefore, the remote server can decrypt it.
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)


I think I did everything bt I am getting wrong result.  the following is test key :

C:\>java TDESStringEncryptor 4CDAEC45ECCD45074FE352D908C7461AAEFB3BB945CD0BBC "This is a Test"

the remote server result:  HMueLH8gSr9y9sUZXfRFlw==
my result is: O0NGwRP9m5EjLBmwJ1viow==

if someone have simple code I wil be greatful, 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
      {
            
            byte [] iv = {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0};

      //AlgorithmParameterSpec paramSpec = new IvParameterSpec(iv);
       IvParameterSpec paramSpec = new IvParameterSpec(iv);

            // convert key to byte array and get it into a key object
            final 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" );
            c2.init(Cipher.ENCRYPT_MODE, key, paramSpec);
            
            byte[] cleartext = data.getBytes();
        byte[] ciphertext = c2.doFinal(cleartext);

            //cleartext = data.getBytes();
            byte [] encodedParameters = c2.getParameters().getEncoded();

           byteArrayToHexString( ciphertext );
            System.out.println("this is test2Hex " + ciphertext);
            return new sun.misc.BASE64Encoder().encode(ciphertext);

      //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 );
            System.out.println("ths is the bte2Hex  " +rslt);
            return rslt;
      }    


}



0
salasadi
Asked:
salasadi
1 Solution
 
CEHJCommented:
Try

return new sun.misc.BASE64Encoder().encode(byteArrayToHexString( ciphertext).getBytes());
0
 
CEHJCommented:
... but if base64 is being used, you shouldn't need to use byteArrayToHexString, so

return new sun.misc.BASE64Encoder().encode(ciphertext);

may be more like it

0
 
Siva Prasanna KumarPrincipal Solutions ArchitectCommented:
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
salasadiAuthor Commented:
Thanks for your replies, I tried both ption but I still gets something diffrent then "HMueLH8gSr9y9sUZXfRFlw=="
May be someone where in the code I am making problem.  how about converting the Hex string "inkey"  to bytes is wrong?  I thought that may be problem, however I am not sure where to start debuging.  

return new sun.misc.BASE64Encoder().encode(byteArrayToHexString( ciphertext).getBytes());
the above retruns this:
M0I0MzQ2QzExM0ZEOUI5MTIzMkMxOUIwMjc1QkUyQTM=

and
return new sun.misc.BASE64Encoder().encode(ciphertext);

retruns:
O0NGwRP9m5EjLBmwJ1viow==

which I already have it this way.  
0
 
CEHJCommented:
Are you sure that their plaintext is also

"This is a Test"

?
0
 
salasadiAuthor Commented:
Yes I send the string and ask them to encrypted.    is the method of getting String Hex key correct?
what Iam concern about is the conversion of the"4CDAEC45ECCD45074FE352D908C7461AAEFB3BB945CD0BBC"  into bytes is incorrect.

final byte[] rawkey = inkey.getBytes();
DESedeKeySpec keyspec = new DESedeKeySpec(rawkey);

THanks
0
 
salasadiAuthor Commented:
which one is he correct method of converting string to bye:

byte[] bts = new byte[inkey.length() / 2];
           for (int i = 0; i < bts.length; i++) {
      bts[i] = (byte) Integer.parseInt(inkey.substring(i, i+2), 16);
            }            
 the result for this one is:  [B@10b62c9

in my code the following function:

final byte[] rawkey = inkey.getBytes();

give this result: [B@923e30


0
 
salasadiAuthor Commented:
ok I got it!!
Thanks for your help guys..
the problem as I was suspecting is the converting of the string key that past to the app.  
I had final byte[] rawkey = inkey.getBytes(); to convert from hex to byte, it works ok but did not give the right result.  I replace it with:




byte[] bts = new byte[inkey.length() / 2];
           for (int i = 0; i < bts.length; i++) {
            bts[i] = (byte) Integer.parseInt(inkey.substring(2*i, 2*i+2), 16);
      }

and evrything work great.
      
                        
0
 
GranModCommented:
PAQed with points refunded (500)

GranMod
Community Support Moderator
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now