Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / Security / June 2006

Tip: Looking for answers? Try searching our database.

Triple DES Bad Data Error Please Help!!!!

Thread view: 
cmureithi@procuri.com - 02 Jun 2006 22:23 GMT
I'm working on decypting Java encrypted text using TripleDES in VB.NET.

Below is
the algorithm submitted by the producer of the ciher text:

Things needed for the consumer (vendor)

1) String used to generate the key and also the algorithm used to
generate the key
  Algorithm for generating the key -- Take a string which you choose
to be secure
  (known to you and the recieving party), do a MD5 of the string and
take the
  first 24 charactrers of this as the KEY

2) Post Parameter field name used to carry the SAML assertion -
SAMLPost

3) IV used in the TripleDES algortithm - currently IV is 00000000

The issue I'm having is that when i use PKCS7 padding, i get a Bad Data

exception. I have to use this padding because the producer used PKCS5
in Java. Below is the decryption code provided by the producer:
package org.security.assertion;

import java.io.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import sun.misc.BASE64Decoder;
import sun.misc.CharacterEncoder;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.math.BigInteger;

/*
* Used for Decrypting of the String
* with Triple DES algorithm of : DESede/ECB/PKCS5Padding
*/

public class DataDecryption implements Serializable {

       /**
         * Generate a DESede SecretKey object
         *
        **/

       //private static String l_strEncodedKey =
"dGhpcyBpcyBhIDI0IGJ5dGUga2V5ICEh";

private static String l_strEncodedKey = "!38lrakm^&pniku#@34557@@ge!";

       private SecretKey getSecretKey()

       {
            SecretKey l_objSecretKey = null;
            byte[] l_byteSecretKey = null;
            DESedeKeySpec l_objDESedeKeySpec = null;
            SecretKeyFactory l_objKeyFactory = null;
            String l_strHpassword = "";
            BigInteger l_bintBigInteger;
           try{

                     try{

                               MessageDigest l_msgdgstMD =
MessageDigest.getInstance(
"MD5" );
                               l_msgdgstMD.update(
l_strEncodedKey.getBytes() );

System.out.println(l_strEncodedKey.getBytes().toString());
                               l_bintBigInteger = new BigInteger( 1,
l_msgdgstMD.digest()
);
                               System.out.println("Key is :" +
l_bintBigInteger.toString());
                               l_strHpassword =
l_bintBigInteger.toString( 16  );
                               System.out.println("Key is :" +
l_strHpassword.toString());
                               l_strHpassword =
l_strHpassword.substring(0,24);
                               System.out.println("Key is :" +
l_strHpassword);

                     }catch ( NoSuchAlgorithmException ns ){

                               System.out.println("An Error Occured in

hashcoding the
password : " + ns);

                      }

                   try{

                       l_byteSecretKey = l_strHpassword.getBytes();
                       System.out.println(l_byteSecretKey);

                    }catch (Exception Ex){

                       System.out.println("An Error Occured while
getting Byte
Secret Key : " + Ex);

                    }

                     try{

                       // Create a DESede key spec from the key
                          l_objDESedeKeySpec = new
DESedeKeySpec(l_byteSecretKey);

                       }catch (java.security.InvalidKeyException Ex){

                               System.out.println("The Key is not
Valid  : " + Ex);

                       }

                     try{

                       // Get the secret key factor for generating
DESede keys
                          l_objKeyFactory =
SecretKeyFactory.getInstance("DESede");

                       }catch (java.security.NoSuchAlgorithmException
Ex){

                               System.out.println("Invalid Algorithm
: " + Ex);

                       }

                       try{

                       // Generate a DESede SecretKey object
                          l_objSecretKey =
l_objKeyFactory.generateSecret(l_objDESedeKeySpec);

                       }catch
(java.security.spec.InvalidKeySpecException Ex){

                               System.out.println("Invalid Key Spec  :

" + Ex);

                       }

             }catch (Exception e){

                       System.out.println("An error occured in
getSecretKey method :
" + e);

             }

               return l_objSecretKey;

       }

       public String getDecryptedData(String p_CipherText) {

               String l_strEncryptedData = "";
               Cipher l_objCipher = null;
               byte[] l_byteEncryptedData = null;

               try{

                       try{
                               // Create a DESede Cipher
                               l_objCipher =
Cipher.getInstance("DESede/ECB/PKCS5Padding");

                       }catch (javax.crypto.NoSuchPaddingException
Ex){

                               System.out.println("Invalid Padding :
" + Ex);

                       }

                       try{
                               // Initialize the cipher and put it
into decrypt mode
                               l_objCipher.init(Cipher.DECRYPT_MODE,
getSecretKey());

                       }catch (java.security.InvalidKeyException Ex){

                               System.out.println("Invalid Key :  " +
Ex);

                       }

                       try{

                       // Decrypt the data
                       System.out.println(new
BASE64Decoder().decodeBuffer(p_CipherText));
                          l_byteEncryptedData =
l_objCipher.doFinal((new
BASE64Decoder()).decodeBuffer(p_CipherText));

                       }catch (java.io.IOException ExIO){

                               System.out.println("An error while
Decoding :  " + ExIO);

                       }catch (javax.crypto.BadPaddingException
Exbadpadding){

                               System.out.println("Bad Padding :  " +
Exbadpadding);

                       }

                       // Byte to String Conversion
                       l_strEncryptedData = new
String(l_byteEncryptedData);

                 }catch (Exception e){

                       System.out.println("An error occured in
getEncryptedData method :
" + e);

                 }
                  return l_strEncryptedData;

       }

}

Using this code, i successfully decrypted the cipher text. Here's my
vb.net code:

   Public Function Decrypt(ByVal cipherString As String, ByVal
useHashing As Boolean) As String
       Dim keyArray As Byte()
       'get the byte code of the string

       Dim toEncryptArray As Byte() =
Convert.FromBase64String(cipherString)

       Dim key As String = "!38lrakm^&pniku#@34557@@ge!";

       If useHashing Then
           'if hashing was used get the hash code with regards to your

key
           Dim hashmd5 As MD5CryptoServiceProvider = New
MD5CryptoServiceProvider
           keyArray =
hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key))
           'Dim str As String = Me.GetAsString(keyArray).Substring(0,
24)
           'keyArray = utf8.GetBytes(str)
           Dim j As Integer
           Dim i As String
           For j = 0 To keyArray.Length - 1
               i = i + Hex(keyArray(j))
           Next
           'Dim i As Int64 = BitConverter.ToInt64(keyArray, 0)

           Dim str As String = i.Substring(0, 24)

           Dim keyArr(23) As Byte
           For j = 0 To str.Length - 1
               keyArr(j) = Byte.Parse(str.Chars(j),
System.Globalization.NumberStyles.AllowHexSpecifier)
               'If Char.IsLetter(str.Chars(j)) Then
               'keyArr(j) = byte.Parse(
               'Else
               'keyArr(j) =
CByte(Microsoft.VisualBasic.Val(str.Chars(j)))
               ' End If
           Next
           keyArray = Nothing
           keyArray = keyArr

           'release any resource held by the MD5CryptoServiceProvider

           hashmd5.Clear()
       Else
           'if hashing was not implemented get the byte code of the
key
           keyArray = ASCIIEncoding.ASCII.GetBytes(key)
       End If

       Dim tdes As TripleDESCryptoServiceProvider = New
TripleDESCryptoServiceProvider

       Dim f As Array = tdes.LegalKeySizes

       'set the secret key for the tripleDES algorithm
       tdes.Key = keyArray
       'mode of operation. there are other 4 modes. We choose
ECB(Electronic code Book)

       tdes.Mode = CipherMode.ECB
       'padding mode(if any extra byte added)
       tdes.Padding = PaddingMode.PKCS7
       Dim d As Array = tdes.LegalBlockSizes()

       tdes.IV = New Byte() {0, 0, 0, 0, 0, 0, 0, 0}

       Dim cTransform As ICryptoTransform = tdes.CreateDecryptor()
       Dim resultArray As Byte() =
cTransform.TransformFinalBlock(toEncryptArray, 0,
toEncryptArray.Length)
       'Release resources held by TripleDes Encryptor
       tdes.Clear()
       'return the Clear decrypted TEXT
       Return UTF8Encoding.UTF8.GetString(resultArray)
       'Return Convert.ToBase64String(resultArray)
   End Function

Any help will be greatly appriciated. Im facing a deadline shortly, so
please help me. thanks in advance.
Mike Amling - 03 Jun 2006 02:02 GMT
> l_strHpassword = l_bintBigInteger.toString( 16  );

  Note that Java's BigInteger.toString(16) omits leading zeros. Does
your VB code omit leading zeros?

> l_objCipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");

  Are the designers aware of how rare the circumstances are in which
ECB is a good choice?

>             Dim j As Integer
>             Dim i As String
>             For j = 0 To keyArray.Length - 1
>                 i = i + Hex(keyArray(j))

  Does this "Hex" function always produce two hex digits? or only one
when 0<=keyArray(j)<=15 ?

>             Next
>             'Dim i As Int64 = BitConverter.ToInt64(keyArray, 0)
>
>             Dim str As String = i.Substring(0, 24)
>
>             Dim keyArr(23) As Byte

  Why only 23? They used 24 in Java.

>             For j = 0 To str.Length - 1
>                 keyArr(j) = Byte.Parse(str.Chars(j),
> System.Globalization.NumberStyles.AllowHexSpecifier)

  I don't know what Byte.Parse(....) does, but the l_byteSecretKey =
l_strHpassword.getBytes() in the supplied Java code does not parse
l_strHpassword as hex digits.

>         tdes.IV = New Byte() {0, 0, 0, 0, 0, 0, 0, 0}

  Note: ECB mode does not use an IV.

--Mike Amling
Jan Peter Stotz - 03 Jun 2006 10:27 GMT
cmureithi@procuri.com schrieb:

> 1) String used to generate the key and also the algorithm used to
> generate the key Algorithm for generating the key -- Take a string which
> you choose to be secure (known to you and the recieving party), do a MD5
> of the string and take the first 24 charactrers of this as the KEY

Please, no. This isn't a good design. There are special algorithms for
cryptographic key generation from a string/password. You should better take
a look onto PKCS#5 or something similar.

Jan


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.