Search code examples
c#.netasp.net-core-3.1tripledes

TRIPLEDES padding is invalid and cannot be removed. c# decrypt


I have a problem when performing a decryption in TRIPLEDES that a provider sends me in HEX: EF69FF79BBD7E8E4EF69FF79BBD7E8E4 with the following key "0123456789ABCDEFFEDCBA9876543210", applying the following method:

 public IActionResult GetTokenTemp1()
        {

            TripleDESCryptoServiceProvider tDESalg = new TripleDESCryptoServiceProvider();
            MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
            tDESalg.Key = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes("0123456789ABCDEFFEDCBA9876543210"));
            byte[] cipherBytes = Convert.FromBase64String("EF69FF79BBD7E8E4EF69FF79BBD7E8E4");
            string finalDecrypt = _3desTest.DecryptTextFromMemory(cipherBytes, tDESalg.Key, tDESalg.IV);
            return Ok(finalDecrypt);
        }
  public static string DecryptTextFromMemory(byte[] Data, byte[] Key, byte[] IV)
        {
            try
            {
                // Create a new MemoryStream using the passed
                // array of encrypted data.
                MemoryStream msDecrypt = new MemoryStream(Data);
                TripleDESCryptoServiceProvider de = new TripleDESCryptoServiceProvider();
               
                var descritor = de.CreateDecryptor(Key, IV);
           
                // Create a CryptoStream using the MemoryStream
                // and the passed key and initialization vector (IV).
                CryptoStream csDecrypt = new CryptoStream(msDecrypt,
                   descritor,
                    CryptoStreamMode.Read);
                
                // Create buffer to hold the decrypted data.
                byte[] fromEncrypt = new byte[Data.Length];

                // Read the decrypted data out of the crypto stream
                // and place it into the temporary buffer.
                csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);
                string es = new UTF8Encoding().GetString(fromEncrypt);
                //Convert the buffer into a string and return it.
                return new UTF8Encoding().GetString(fromEncrypt);
            }
            catch (CryptographicException e)
            {
                Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
                return null;
            }
        }

When I leave the default padding or any other to zero or none, I get the following error "adding is invalid and cannot be removed.", but when I leave the padding at zero or none tripleDescryptorService.Padding = PaddingMode.None I get a format: padding.none

I don't know what to do very well, when I do it on this page: https://neapay.com/online-tools/des-calculator.html?data=EF69FF79BBD7E8E4EF69FF79BBD7E8E4&key=0123456789ABCDEFFEDCBA9876543210&algo=3DES&decr=true

I get the desired result.

I'm already desperate, I'm not very expert in encryption.

Thank you so much


Solution

  • The website uses neither a padding nor an IV. Therefore in the code the padding must be disabled and the ECB mode must be applied.

    Furthermore the website expects a hex encoded key and ciphertext and returns the decrypted data also hex encoded, which therefore must not be UTF-8 decoded in the code:

    public static byte[] DecryptTextFromMemory(byte[] encryptedData, byte[] key)
    {
        using (TripleDESCryptoServiceProvider tripleDES = new TripleDESCryptoServiceProvider())
        {
            tripleDES.Key = key;
            tripleDES.Padding = PaddingMode.None;
            tripleDES.Mode = CipherMode.ECB;
    
            byte[] decryptedData = new byte[encryptedData.Length];
            using (MemoryStream msDecrypt = new MemoryStream(encryptedData))
            {
                ICryptoTransform decryptor = tripleDES.CreateDecryptor(tripleDES.Key, null);
                using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                {
                    csDecrypt.Read(decryptedData, 0, decryptedData.Length);
                }
            }
    
            return decryptedData;
        }
    }
    

    For the hex encoding and decoding you can use arbitrary methods, e.g. from here.

    With this the code:

    byte[] data = HexStringToByteArray("EF69FF79BBD7E8E4EF69FF79BBD7E8E4");
    byte[] key = HexStringToByteArray("0123456789ABCDEFFEDCBA9876543210");
    Console.WriteLine(ByteArrayToHexString(DecryptTextFromMemory(data, key)));
    

    returns the result of the website:

    00000000003331720000000000333172
    

    Please note: Your last change is not useful because it applies conversions and algorithms that are not consistent with the website.