2

I have legacy server uses TripleDES encryption in .NET/C#.

Need to decrypt text by using PHP.

I wrote PHP code but it's not able to decrypt message generated form C#.

C# Code

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


namespace testns
{
    class Program
    {
        static void Main(string[] args)
        {
            string key = "123456789012345678901234";
            string iv = "12345678";

            string text = "this is just test string";
            string e = Program.EncryptTripleDES(text, key, iv);
            Console.WriteLine(e);

            string d = Program.DecryptTripleDES(e, key, iv);
            Console.WriteLine(d);

            // Return
            // QDIRAeQ/O1hhjN4XqgcETG7IChnybCqZ
            // this is just test string
        }

        private static string EncryptTripleDES(string neqs, string nafKeyCode, string nafIvCode)
        {

            byte[] rgbKey = Encoding.UTF8.GetBytes(nafKeyCode);
            byte[] rgbIV = Encoding.UTF8.GetBytes(nafIvCode);

            string sEncrypted = string.Empty;

            if (!String.IsNullOrEmpty(neqs))
            {
                TripleDESCryptoServiceProvider cryptoProvider = new TripleDESCryptoServiceProvider();
                cryptoProvider.Mode = CipherMode.CBC;
                cryptoProvider.Padding = PaddingMode.None;

                byte[] buffer = Encoding.UTF8.GetBytes(neqs);
                MemoryStream ms = new MemoryStream();
                CryptoStream cs = new CryptoStream(ms, cryptoProvider.CreateEncryptor(rgbKey, rgbIV), CryptoStreamMode.Write);
                cs.Write(buffer, 0, buffer.Length);
                cs.FlushFinalBlock();

                sEncrypted = Convert.ToBase64String(ms.ToArray());

            }

            return sEncrypted;
        }

        private static string DecryptTripleDES(string neqs, string nafKeyCode, string nafIvCode)
        {

            byte[] rgbKey = Encoding.UTF8.GetBytes(nafKeyCode);
            byte[] rgbIV = Encoding.UTF8.GetBytes(nafIvCode);

            string decryptedText = string.Empty;

            if (!String.IsNullOrEmpty(neqs))
            {
                TripleDESCryptoServiceProvider cryptoProvider = new TripleDESCryptoServiceProvider();
                cryptoProvider.Mode = CipherMode.CBC;
                cryptoProvider.Padding = PaddingMode.None;
                byte[] buffer = Convert.FromBase64String(neqs);
                MemoryStream ms = new MemoryStream(buffer);
                CryptoStream cs = new CryptoStream(ms, cryptoProvider.CreateDecryptor(rgbKey, rgbIV), CryptoStreamMode.Read);
                StreamReader sr = new StreamReader(cs);
                decryptedText = sr.ReadToEnd();

                //(new Logs()).LogException(decryptedText);
            }

            return decryptedText;
        }
    }
}

PHP Code

$key = '123456789012345678901234';
$iv  = '12345678';
$text = 'this is just test string';

$e = openssl_encrypt($text, 'des-ede3-cbc', $key, 0, $iv);
echo $e . "<br /><br />";

$d = openssl_decrypt($e, 'des-ede3-cbc', $key, 0, $iv);
echo $d . "<br /><br />";

// Return
// QDIRAeQ/O1hhjN4XqgcETG7IChnybCqZqN3DpVbYFwk=
// this is just test string

Got from PHP

QDIRAeQ/O1hhjN4XqgcETG7IChnybCqZqN3DpVbYFwk=

Got from C#

QDIRAeQ/O1hhjN4XqgcETG7IChnybCqZ

As you an see it's almost the same for PHP has extra qN3DpVbYFwk= characters.

What I am doing wrong? It is something to do with padding?

Thanks

1 Answers1

1

It looks like the problem is that you have turned padding off (PaddingMode.None) in your C# code and Padding is turned on (by default) in your PHP code.

The OpenSSL library methods openssl_encrypt and openssl_decrypt have padding turned on by default when you pass 0 as the options parameter. The default padding is PKCS#7.

So to solve your issue you will either need to add PaddingMode.PKCS7 to your C# code (which I personally recommend):

cryptoProvider.Padding = PaddingMode.PKCS7;

Or you turn off the padding in PHP using OPENSSL_ZERO_PADDING. Remember that in PHP you will need to add the flag OPENSSL_ZERO_PADDING to both openssl_encrypt and openssl_decrypt.

example:

$e = openssl_encrypt($text, 'des-ede3-cbc', $key, OPENSSL_ZERO_PADDING, $iv);

Important
Remember the padding options must be set on both encrypt and decrypt modes.

Barns
  • 4,850
  • 3
  • 17
  • 31
  • Thanks Barns! I suspected that it's something to do with padding. You helped me to resolve this issue! – Aleksandr Korsukov Aug 10 '19 at 05:31
  • I'm glad I could help and I appreciate you letting me know that it resolved your issue. I realize this is a legacy service, but if anyway possible I highly recommend you switch to AES. But I'm sure I am not the first to make that suggestion. Happy coding – Barns Aug 10 '19 at 22:44