Question

We have a Java client that sending us some encrypted data 1. A random string is encrypted using RSA and public key we provided them offline. 2. using the key generated in step1 they encrypt the data using alg_tripleDES_CBC = http://www.w3.org/2001/04/xmlenc#tripledes-cbc

I was able to decrypt the key from 1st step like this ... which is working.

public static string DecryptKey(string encryptedKey)
    {
        X509Certificate2 cert = new X509Certificate2("c:\\test.pfx", "test");
        RSACryptoServiceProvider privateKeyProvider = (RSACryptoServiceProvider)cert.PrivateKey;

        string decryptedKey = System.Text.Encoding.UTF8.GetString(privateKeyProvider.Decrypt(Convert.FromBase64String(encryptedKey), false));

        return decryptedKey;

    }

And I have this code to decrypt the data using the key generated from 1st step.

 public static string DecryptString(string Message, string Passphrase)
    {
        byte[] Results;
        System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();

        MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
        byte[] TDESKey = HashProvider.ComputeHash(UTF8.GetBytes(Passphrase));

        TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider();

        TDESAlgorithm.Key = TDESKey;
        TDESAlgorithm.Mode = CipherMode.ECB;
        TDESAlgorithm.Padding = PaddingMode.PKCS7;

        byte[] DataToDecrypt = Convert.FromBase64String(Message);

        try
        {
            ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor();
            Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length);
        }
        finally
        {
            TDESAlgorithm.Clear();
            HashProvider.Clear();
        }

        return UTF8.GetString(Results);
    }

And the second step fails with this exception.

   System.Security.Cryptography.CryptographicException: Bad Data.

   at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)
   at System.Security.Cryptography.Utils._DecryptData(SafeKeyHandle hKey, Byte[] data, Int32 ib, Int32 cb, Byte[]& outputBuffer, Int32 outputOffset, PaddingMode PaddingMode, Boolean fDone)
   at System.Security.Cryptography.CryptoAPITransform.TransformFinalBlock(Byte[] inputBuffer, Int32 inputOffset, Int32 inputCount)
   at ConsoleApplication3.Program.DecryptString(String Message, String Passphrase) in C:\Documents and Settings\rjaladi\Desktop\ConsoleApplication3\ConsoleApplication3\Program.cs:line 66
   at ConsoleApplication3.Program.Main(String[] args) in C:\Documents and Settings\rjaladi\Desktop\ConsoleApplication3\ConsoleApplication3\Program.cs:line 22 

What is that I need to check with our client? I know that there is something wrong with the parameters we are passing to TDES. Any help?

EDIT: Corresponding Java code that encrypts the message.

public String encryptText(String plainText) throws Exception{

  byte[] plaintext = plainText.getBytes();
  byte[] tdesKeyData = key;
  byte[] myIV = initializationVector;

  Cipher c3des = Cipher.getInstance(""DESede/CBC/NoPadding"");
  SecretKeySpec    myKey = new SecretKeySpec(tdesKeyData, "DESede");
  IvParameterSpec ivspec = new IvParameterSpec(myIV);
     c3des.init(Cipher.ENCRYPT_MODE, myKey, ivspec);
  byte[] cipherText = c3des.doFinal(plaintext);
  sun.misc.BASE64Encoder obj64=new sun.misc.BASE64Encoder();
  return obj64.encode(cipherText);
 }
Was it helpful?

Solution

Your exception is being thrown in _DecryptData(...) which I notice includes a PaddingMode parameter. Padding at the end of that last block will be checked and an error thrown if incorrect padding is found. I suggest that you check with whoever is sending the data to see what padding mode they are using. You will need to use the same padding mode when decrypting.

As @klartrex says, you should not use ECB mode, it leaks information; see here for a (literal) illustration. Use either CBC or CTR mode instead if you can persuade the other end to do so.

OTHER TIPS

Probably this fails:

TDESAlgorithm.Mode = CipherMode.ECB;

You should use CBC ciphermode if you used CBC to encrypt the Java. And its not recommended to use ECB anyways, because it has some security flaws.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top