Search code examples
c#phpencryptionmcrypttripledes

TripleDES encription not getting same results in c# and PHP


C# returns the following base64 encoded string:

joxzS5XnP63ymrhy6t4ogWK9TxwfwD83

below is the code in c#

us

ing System.IO;
using System;
using System.Text;
using System.Security.Cryptography;

class Program
{
    static void Main()
    {
        // Read in every line in the file.
        using (StreamReader reader = new StreamReader("input.txt"))
        {
            string abc = "string to encrypt";
            Program p = new Program();
            string value =    p.Encrypt(abc, true);
            Console.Write(value);
        }
    }

    public string Encrypt(string toEncrypt, bool useHashing)
        {
            byte[] keyArray;
            byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toEncrypt);

            //System.Configuration.AppSettingsReader settingsReader = new AppSettingsReader();
            // Get the key from config file
            string key = "encrypt key";
            //System.Windows.Forms.MessageBox.Show(key);
            if (useHashing)
            {
                MD5CryptoServiceProvider hashmd5 = new MD5CryptoServiceProvider();
                keyArray = hashmd5.ComputeHash(UTF8Encoding.UTF8.GetBytes(key));
                hashmd5.Clear();
            }
            else
                keyArray = UTF8Encoding.UTF8.GetBytes(key);

            TripleDESCryptoServiceProvider tdes = new TripleDESCryptoServiceProvider();
            tdes.Key = keyArray;
            tdes.Mode = CipherMode.ECB;
            tdes.Padding = PaddingMode.PKCS7;

            ICryptoTransform cTransform = tdes.CreateEncryptor();
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, 0, toEncryptArray.Length);
            tdes.Clear();
            return Convert.ToBase64String(resultArray, 0, resultArray.Length);
        }


}

I am using MCrypt library in PHP which returns

ThPKJ1BPJLeUwJtIT/zAs3ocZ2s6SU+M

PHP code:

$str = "string to encrypt";

$input = utf8_encode($str);
$key = "encrypt key";
echo apiEncode($input, $key);


function apiEncode($data, $secret)
{    
  //Generate a key from a hash
  $key = md5(utf8_encode($secret), true);
  //Create init vector  
  $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_ecb), MCRYPT_RAND); 

  //Pad for PKCS7
  $blockSize = mcrypt_get_block_size('tripledes', 'ecb');
  $len = strlen($data);
  $pad = $blockSize - ($len % $blockSize);
  $data .= str_repeat(chr($pad), $pad);

  //Encrypt data
  $encData = mcrypt_encrypt('tripledes', $key, $data, 'ecb'); //, $iv);
  return base64_encode($encData);
}

apart from the above I have tried various other solutions found at so

tripledes encryption not yielding same results in PHP and C#

TripleDES Encrypting in C# and PHP not coming out the same (PKCS7, ECB)?


Solution

  • Considering the Security vulnerabilities of DES and TripleDES, implemented AES/RIJNDAEL_256 algo at both the sides.

    C#

        public String DecryptRJ256(string cypher, string KeyString, string IVString)
        {
            string sRet = string.Empty;
            RijndaelManaged rj = new RijndaelManaged();
            UTF8Encoding encoding = new UTF8Encoding();
    
            byte[] decbuff = Convert.FromBase64String(cypher);
    
            try
            {
                byte[] Key = encoding.GetBytes(KeyString);
                byte[] IV = encoding.GetBytes(IVString);
    
                rj.Padding = PaddingMode.PKCS7;
                rj.Mode = CipherMode.CBC;
                rj.KeySize = 256;
                rj.BlockSize = 256;
                rj.Key = Key;
                rj.IV = IV;
                MemoryStream ms = new MemoryStream(decbuff);
    
                using (CryptoStream cs = new CryptoStream(ms, rj.CreateDecryptor(Key, IV), CryptoStreamMode.Read))
                {
                    using (StreamReader sr = new StreamReader(cs))
                    {
                        sRet = sr.ReadToEnd();
                    }
                }
            }
            finally
            {
                rj.Clear();
            }
            return sRet;
        }
    
    public string Encrypt(string message, string KeyString, string IVString)
        {
            byte[] Key = ASCIIEncoding.UTF8.GetBytes(KeyString);
            byte[] IV = ASCIIEncoding.UTF8.GetBytes(IVString);
    
            string encrypted = null;
            RijndaelManaged rj = new RijndaelManaged();
            rj.BlockSize = 256;
            rj.Key = Key;
            rj.IV = IV;
            rj.Mode = CipherMode.CBC;
    
            try
            {
                MemoryStream ms = new MemoryStream();
    
                using (CryptoStream cs = new CryptoStream(ms, rj.CreateEncryptor(Key, IV), CryptoStreamMode.Write))
                {
                    using (StreamWriter sw = new StreamWriter(cs))
                    {
                        sw.Write(message);
                        sw.Close();
                    }
                    cs.Close();
                }
                byte[] encoded = ms.ToArray();
                encrypted = Convert.ToBase64String(encoded);
    
                ms.Close();
            }
            catch (CryptographicException e)
            {
                Console.WriteLine("A Cryptographic error occurred: {0}", e.Message);
                return null;
            }
            catch (UnauthorizedAccessException e)
            {
                Console.WriteLine("A file error occurred: {0}", e.Message);
                return null;
            }
            catch (Exception e)
            {
                Console.WriteLine("An error occurred: {0}", e.Message);
            }
            finally
            {
                rj.Clear();
            }
    
            return encrypted;
        }
    

    PHP

    public function apiEncode($text, $key, $iv)
    {
        // to append string with trailing characters as for PKCS7 padding scheme
        $block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
        $padding = $block - (strlen($text) % $block);
        $text .= str_repeat(chr($padding), $padding);
    
        $crypttext = mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $iv);
        return base64_encode($crypttext);
    }
    
    publc function apiDecode($text, $key, $iv){
    
        $text = base64_decode($text);
        $crypttext = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $text, MCRYPT_MODE_CBC, $iv);
        return $crypttext;
    }