Search code examples
phpvb.netencryptiontripledes

Encrypt in VB.NET and Decrypt in PHP


I am trying to write a function in PHP and in VB.NET that uses Triple DES to pass in BOTH directions encrypted data. The problem, is that when I try to decrypt a string encrypted in VB.NET using PHP, I get an error message saying that the block size of the IV must match.

The class I wrote in VB.NET, is as follows and is fully functional as it will encrypt and decrypt its own blocks flawlessly.

    Imports System
    Imports System.Text
    Imports System.IO
    Imports System.Security.Cryptography

    Public Class Cipher

        Dim method As TripleDESCryptoServiceProvider
        Dim key As Byte()

        Public Property Password() As String
            Get
                Return System.Text.Encoding.Unicode.GetString(Key)
            End Get
            Set(value As String)
                key = System.Text.Encoding.Unicode.GetBytes(value)
            End Set
        End Property

        Public Function Encrypt(data As String) As String
            Dim ms As New System.IO.MemoryStream

            ' Create the encoder to write to the stream.
            Dim dataBytes() As Byte = System.Text.Encoding.Unicode.GetBytes(data)
            Dim encStream As New CryptoStream(ms, method.CreateEncryptor(), System.Security.Cryptography.CryptoStreamMode.Write)

            ' Use the crypto stream to write the byte array to the stream.
            encStream.Write(dataBytes, 0, dataBytes.Length)
            encStream.FlushFinalBlock()

            ' IV and Ciphered string are each Base64'd and seperated by a comma, then the whole result is Base64'd
            Return Convert.ToBase64String(System.Text.Encoding.Unicode.GetBytes(Convert.ToBase64String(method.IV) & "," & Convert.ToBase64String(ms.ToArray)))
        End Function

        Public Function Decrypt(data As String) As String
            ' Convert the encrypted text string to a byte array.

            Dim partDecoded As String = System.Text.Encoding.Unicode.GetString(Convert.FromBase64String(data))
            Dim dataBytes() As Byte

            If InStr(partDecoded, ",") > 0 Then

                Dim parts() As String = Split(partDecoded, ",")

                ' Get IV from first part
                method.IV = Convert.FromBase64String(parts(0))

                ' Get ciphered data from second part
                dataBytes = Convert.FromBase64String(parts(1))

                ' Create the stream.
                Dim ms As New System.IO.MemoryStream
                ' Create the decoder to write to the stream.
                Dim decStream As New CryptoStream(ms, method.CreateDecryptor(), System.Security.Cryptography.CryptoStreamMode.Write)

                ' Use the crypto stream to write the byte array to the stream.
                decStream.Write(dataBytes, 0, dataBytes.Length)
                decStream.FlushFinalBlock()

                ' Convert the plaintext stream to a string.
                Return System.Text.Encoding.Unicode.GetString(ms.ToArray)
            Else
                Return False
            End If

        End Function

        Public Sub New()
            method = New TripleDESCryptoServiceProvider
            method.Mode = CipherMode.CFB
            method.GenerateIV()
        End Sub
    End Class

Example usage of the above class

    Dim c As New Cipher
    c.Password = "12345"

    Dim encrypted As String = c.Encrypt("hello")
    Debug.Print(encrypted)

    Dim decrypted As String = c.Decrypt(encrypted)
    Debug.Print(decrypted)

Now I also have the following PHP code which ALSO works (by itself)

    class Cipher {
        private $iv;
        private $securekey;

        function __construct($key) {
            $this->securekey = $key;
        }

        function encrypt($string) {
            $this->iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_CFB),MCRYPT_DEV_RANDOM);
            $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_3DES, $this->securekey, $string, MCRYPT_MODE_CFB, $this->iv));
            return base64_encode(base64_encode($this->iv) . ',' . $encrypted);
        }

        function decrypt($string) {
            $decrypt = base64_decode($string);
            if(strpos($decrypt,',') > 0) {
                $decrypt = explode(',', $decrypt);
                $this->iv = base64_decode($decrypt[0]);
                return trim(mcrypt_decrypt(MCRYPT_3DES, $this->securekey, base64_decode($decrypt[1]), MCRYPT_MODE_CFB, $this->iv));
            } else {
                return false;
            }
        }
    }

PHP Example Usage

    $c = new Cipher("12345");
    $encrypted = $c->encrypt("hello");
    echo 'Encrypted: ' . $encrypted . '<br />';

    $decrypted = $c->decrypt($encrypted);
    echo 'Decrypted: ' . $decrypted . '<br />';

    $vb = "MwBOAEoAOQBjAEgAcQAyAC8ASABzAD0ALABmAEUAOQBaAHYAVwBzAFUAYQB3AFYARwBGAHUANABLAGUAVgB3AFcAaABRAD0APQA=";
    echo 'VB.NET Dec: ' . $c->decrypt($vb);

What I have included above in the PHP usage, is the Base64 string made with VB.NET that decodes PERFECTLY in VB.NET as the variable $vb.

This is driving me absolutely batty, as the code is correct, and functional -- in both cases -- so what am I missing and can you point out / fix the problem. I do not wish to use Rijndael, or explore other cipher methods, as this one is well established that works across multiple devices natively (iOS, Android, Windows, Linux, etc.).


Solution

  • Since no one was able to provide a fully functional BI-DIRECTIONAL solution, I have taken the liberty to provide one for the community on this article.

    The problem, is that PHP does not conform to the standards by forcing the strings to be padded in order to match. Presently, there is no known way to reliably pass the IV if randomly generated between .NET and PHP (if you do discover how, or this changes, please feel free to revise this).

    Following is the COMPLETE solution for encrypting data using Triple DES in a manner that is compatible with .NET and PHP which allows for bi-directional Triple DES encrypted communication. This method is also compatible with Java, Delphi, Objective-C, and many other languages, however such code is not going to be supplied here as that is not a solution to the posted question.


    VB.NET Triple DES Class

        Imports System
        Imports System.Text
        Imports System.IO
        Imports System.Security.Cryptography
    
        Public Class TripleDES
    
            Private bPassword As Byte()
            Private sPassword As String
    
            Public Sub New(Optional ByVal Password As String = "password")
                ' On Class Begin
                Me.Password = Password
            End Sub
    
            Public ReadOnly Property PasswordHash As String
                Get
                    Dim UTF8 As System.Text.UTF8Encoding = New System.Text.UTF8Encoding
                    Return UTF8.GetString(bPassword)
                End Get
            End Property
    
            Public Property Password() As String
                Get
                    Dim UTF8 As System.Text.UTF8Encoding = New System.Text.UTF8Encoding
                    Return sPassword
                End Get
                Set(value As String)
                    Dim UTF8 As System.Text.UTF8Encoding = New System.Text.UTF8Encoding
                    Dim HashProvider As MD5CryptoServiceProvider = New MD5CryptoServiceProvider()
                    bPassword = HashProvider.ComputeHash(UTF8.GetBytes(value))
                    sPassword = value
                End Set
            End Property
    
        #Region "Encrypt"
    
            ' Encrypt using Password from Property Set (pre-hashed)
            Public Function Encrypt(ByVal Message As String) As String
                Dim Results() As Byte
                Dim UTF8 As System.Text.UTF8Encoding = New System.Text.UTF8Encoding
                Using HashProvider As MD5CryptoServiceProvider = New MD5CryptoServiceProvider()
                    Dim TDESKey() As Byte = bPassword
                    Using TDESAlgorithm As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider() With {.Key = TDESKey, .Mode = CipherMode.ECB, .Padding = PaddingMode.PKCS7}
                        Dim DataToEncrypt() As Byte = UTF8.GetBytes(Message)
                        Try
                            Dim Encryptor As ICryptoTransform = TDESAlgorithm.CreateEncryptor
                            Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length)
                        Finally
                            TDESAlgorithm.Clear()
                            HashProvider.Clear()
                        End Try
                    End Using
                End Using
                Return Convert.ToBase64String(Results)
            End Function
    
            ' Encrypt using Password as byte array
            Private Function Encrypt(ByVal Message As String, ByVal Password() As Byte) As String
                Dim Results() As Byte
                Dim UTF8 As System.Text.UTF8Encoding = New System.Text.UTF8Encoding
                Using HashProvider As MD5CryptoServiceProvider = New MD5CryptoServiceProvider()
                    Dim TDESKey() As Byte = HashProvider.ComputeHash(UTF8.GetBytes(UTF8.GetString(Password)))
                    Using TDESAlgorithm As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider() With {.Key = TDESKey, .Mode = CipherMode.ECB, .Padding = PaddingMode.PKCS7}
                        Dim DataToEncrypt() As Byte = UTF8.GetBytes(Message)
                        Try
                            Dim Encryptor As ICryptoTransform = TDESAlgorithm.CreateEncryptor
                            Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length)
                        Finally
                            TDESAlgorithm.Clear()
                            HashProvider.Clear()
                        End Try
                    End Using
                End Using
                Return Convert.ToBase64String(Results)
            End Function
    
            ' Encrypt using Password as string
            Public Function Encrypt(ByVal Message As String, ByVal Password As String) As String
                Dim Results() As Byte
                Dim UTF8 As System.Text.UTF8Encoding = New System.Text.UTF8Encoding
                ' Step 1. We hash the Passphrase using MD5
                ' We use the MD5 hash generator as the result is a 128 bit byte array
                ' which is a valid length for the Triple DES encoder we use below
                Using HashProvider As MD5CryptoServiceProvider = New MD5CryptoServiceProvider()
                    Dim TDESKey() As Byte = HashProvider.ComputeHash(UTF8.GetBytes(Password))
    
                    ' Step 2. Create a new TripleDESCryptoServiceProvider object
    
                    ' Step 3. Setup the encoder
                    Using TDESAlgorithm As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider() With {.Key = TDESKey, .Mode = CipherMode.ECB, .Padding = PaddingMode.PKCS7}
                        ' Step 4. Convert the input string to a byte[]
    
                        Dim DataToEncrypt() As Byte = UTF8.GetBytes(Message)
    
                        ' Step 5. Attempt to encrypt the string
                        Try
                            Dim Encryptor As ICryptoTransform = TDESAlgorithm.CreateEncryptor
                            Results = Encryptor.TransformFinalBlock(DataToEncrypt, 0, DataToEncrypt.Length)
                        Finally
                            ' Clear the Triple Des and Hashprovider services of any sensitive information
                            TDESAlgorithm.Clear()
                            HashProvider.Clear()
                        End Try
                    End Using
                End Using
    
                ' Step 6. Return the encrypted string as a base64 encoded string
                Return Convert.ToBase64String(Results)
            End Function
        #End Region
    
        #Region "Decrypt"
            ' Decrypt using Password from Property (pre-hashed)
            Public Function Decrypt(ByVal Message As String) As String
                Dim Results() As Byte
                Dim UTF8 As System.Text.UTF8Encoding = New System.Text.UTF8Encoding
                Using HashProvider As MD5CryptoServiceProvider = New MD5CryptoServiceProvider()
                    Dim TDESKey() As Byte = Me.bPassword
                    Using TDESAlgorithm As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider() With {.Key = TDESKey, .Mode = CipherMode.ECB, .Padding = PaddingMode.PKCS7}
                        Dim DataToDecrypt() As Byte = Convert.FromBase64String(Message)
                        Try
                            Dim Decryptor As ICryptoTransform = TDESAlgorithm.CreateDecryptor
                            Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length)
                        Finally
                            TDESAlgorithm.Clear()
                            HashProvider.Clear()
                        End Try
                    End Using
                End Using
                Return UTF8.GetString(Results)
            End Function
    
            ' Decrypt using Password as Byte array
            Public Function Decrypt(ByVal Message As String, ByVal Password() As Byte) As String
                Dim Results() As Byte
                Dim UTF8 As System.Text.UTF8Encoding = New System.Text.UTF8Encoding
                Using HashProvider As MD5CryptoServiceProvider = New MD5CryptoServiceProvider()
                    Dim TDESKey() As Byte = HashProvider.ComputeHash(UTF8.GetBytes(UTF8.GetString(Password)))
                    Using TDESAlgorithm As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider() With {.Key = TDESKey, .Mode = CipherMode.ECB, .Padding = PaddingMode.PKCS7}
                        Dim DataToDecrypt() As Byte = Convert.FromBase64String(Message)
                        Try
                            Dim Decryptor As ICryptoTransform = TDESAlgorithm.CreateDecryptor
                            Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length)
                        Finally
                            TDESAlgorithm.Clear()
                            HashProvider.Clear()
                        End Try
                    End Using
                End Using
                Return UTF8.GetString(Results)
            End Function
    
    
            ' Decrypt using Password as string
            Public Function Decrypt(ByVal Message As String, ByVal Password As String) As String
                Dim Results() As Byte
                Dim UTF8 As System.Text.UTF8Encoding = New System.Text.UTF8Encoding
    
                ' Step 1. We hash the pass phrase using MD5
                ' We use the MD5 hash generator as the result is a 128-bit byte array
                ' which is a valid length for the Triple DES encoder we use below
                Using HashProvider As MD5CryptoServiceProvider = New MD5CryptoServiceProvider()
                    Dim TDESKey() As Byte = HashProvider.ComputeHash(UTF8.GetBytes(Password))
    
                    ' Step 2. Create a new TripleDESCryptoServiceProvider object
                    ' Step 3. Setup the decoder
                    Using TDESAlgorithm As TripleDESCryptoServiceProvider = New TripleDESCryptoServiceProvider() With {.Key = TDESKey, .Mode = CipherMode.ECB, .Padding = PaddingMode.PKCS7}
    
                        ' Step 4. Convert the input string to a byte[]
                        Dim DataToDecrypt() As Byte = Convert.FromBase64String(Message)
                        ' Step 5. Attempt to decrypt the string
                        Try
                            Dim Decryptor As ICryptoTransform = TDESAlgorithm.CreateDecryptor
                            Results = Decryptor.TransformFinalBlock(DataToDecrypt, 0, DataToDecrypt.Length)
                        Finally
    
                            ' Clear the Triple Des and Hash provider services of any sensitive information
                            TDESAlgorithm.Clear()
                            HashProvider.Clear()
                        End Try
                    End Using
                End Using
    
                ' Step 6. Return the decrypted string in UTF8 format
                Return UTF8.GetString(Results)
            End Function
    
        #End Region
    
        End Class
    

    VB.NET Triple DES Class Usage

        Dim tdes As New TripleDES("12345")
        Dim vbEncrypted = tdes.Encrypt("Encrypted using VB.NET")
        Dim phpEncrypted = "5Ittyr0+jiI7QQmPrvSVnMc9MEWQCjAN"
    
        Debug.Print("PHP Encrypted: " & phpEncrypted)
        Debug.Print("VB Encrypted: " & vbEncrypted)
        Debug.Print("PHP Encrypted (decrypted result): " & tdes.Decrypt(phpEncrypted))
        Debug.Print("VB Encrypted (decrypted result): " & tdes.Decrypt(vbEncrypted))
    

    PHP Triple DES Class

        class TripleDES {
            private $bPassword;
            private $sPassword;
    
            function __construct($Password) {
                $this->bPassword  = md5(utf8_encode($Password),TRUE);
                $this->bPassword .= substr($this->bPassword,0,8);
                $this->sPassword - $Password;
            }
    
            function Password($Password = "") {
                if($Password == "") {
                    return $this->sPassword;
                } else {
                    $this->bPassword  = md5(utf8_encode($Password),TRUE);
                    $this->bPassword .= substr($this->bPassword,0,8);
                    $this->sPassword - $Password;
                }
            }
    
            function PasswordHash() {
                return $this->bPassword;
            }
    
            function Encrypt($Message, $Password = "") {
                if($Password <> "") { $this->Password($Password); }
                $size=mcrypt_get_block_size('tripledes','ecb');
                $padding=$size-((strlen($Message)) % $size);
                $Message .= str_repeat(chr($padding),$padding);
                $encrypt  = mcrypt_encrypt('tripledes',$this->bPassword,$Message,'ecb');
                return base64_encode($encrypt);
            }
    
            function Decrypt($message, $Password = "") {
                if($Password <> "") { $this->Password($Password); }
                return trim(mcrypt_decrypt('tripledes', $this->bPassword, base64_decode($message), 'ecb'), ord(2));
            }
    
        }
    

    PHP Triple DES Class Usage

        $tdes = new TripleDES("12345");
    
        $phpEncrypted = $tdes->encrypt("Encrypted using PHP");
        $vbEncrypted = "5Ittyr0+jiI7QQmPrvSVnP3s2CeoTJmF"; // Encrypted using VB.NET
    
        echo "PHP Encrypted: " . $phpEncrypted . '<br />';
        echo "VB Encrypted: " . $vbEncrypted . '<br />';
        echo "PHP Encrypted (decrypted result): " . $tdes->Decrypt($phpEncrypted) . '<br />';
        echo "VB Encrypted (decrypted result): " . $tdes->Decrypt($vbEncrypted) . '<br />';
    

    I did what I could to make both classes usability level identical as the languages would allow naturally. Since PHP does not allow overloading functions, I had to use the password as an optional parameter, which is a string value. The VB.NET solution has an additional override that allows you to pass the byte value of the password string on encrypt/decrypt functions. The example code provided to show the usage for each, shows the most simplistic form of instantiating the object which both classes allow for setting the password on object creation.

    For anyone else out there that was bashing their brains trying to find a WORKING bi-directional solution for Triple DES (and did not want to be forced into the box that everyone seems to be pointing to -- Rijndael), then this solution is for you, and you can stop banging your head against the wall.

    Added a C# translation of the VB.NET TripleDES class

    C# Class ( Added [2017-01-11] )

    using System;
    using System.Security.Cryptography;
    
    public class TripleDES {
    
        private byte[] bPassword;
    
        private string sPassword;
        public TripleDES( string Password = "password" ) {
            // On Class Begin
            this.Password = Password;
        }
    
        public string PasswordHash {
            get {
                System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
                return UTF8.GetString( bPassword );
            }
        }
    
        public string Password {
            get {
                System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
                return sPassword;
            }
            set {
                System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
                MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider();
                bPassword = HashProvider.ComputeHash( UTF8.GetBytes( value ) );
                sPassword = value;
            }
        }
    
        #region "Encrypt"
    
        // Encrypt using Password from Property Set (pre-hashed)
        public string Encrypt( string Message ) {
            byte[] Results = null;
            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
            using ( MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider() ) {
                byte[] TDESKey = bPassword;
                using ( TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider { Key = TDESKey, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 } ) {
                    byte[] DataToEncrypt = UTF8.GetBytes( Message );
                    try {
                        ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
                        Results = Encryptor.TransformFinalBlock( DataToEncrypt, 0, DataToEncrypt.Length );
                    } finally {
                        TDESAlgorithm.Clear();
                        HashProvider.Clear();
                    }
                }
            }
            return Convert.ToBase64String( Results );
        }
    
        // Encrypt using Password as byte array
        private string Encrypt( string Message, byte[] Password ) {
            byte[] Results = null;
            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
            using ( MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider() ) {
                byte[] TDESKey = HashProvider.ComputeHash( UTF8.GetBytes( UTF8.GetString( Password ) ) );
                using ( TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider { Key = TDESKey, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 } ) {
                    byte[] DataToEncrypt = UTF8.GetBytes( Message );
                    try {
                        ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
                        Results = Encryptor.TransformFinalBlock( DataToEncrypt, 0, DataToEncrypt.Length );
                    } finally {
                        TDESAlgorithm.Clear();
                        HashProvider.Clear();
                    }
                }
            }
            return Convert.ToBase64String( Results );
        }
    
        // Encrypt using Password as string
        public string Encrypt( string Message, string Password ) {
            byte[] Results = null;
            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
            // Step 1. We hash the Passphrase using MD5
            // We use the MD5 hash generator as the result is a 128 bit byte array
            // which is a valid length for the Triple DES encoder we use below
            using ( MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider() ) {
                byte[] TDESKey = HashProvider.ComputeHash( UTF8.GetBytes( Password ) );
    
                // Step 2. Create a new TripleDESCryptoServiceProvider object
    
                // Step 3. Setup the encoder
                using ( TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider { Key = TDESKey, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 } ) {
                    // Step 4. Convert the input string to a byte[]
    
                    byte[] DataToEncrypt = UTF8.GetBytes( Message );
    
                    // Step 5. Attempt to encrypt the string
                    try {
                        ICryptoTransform Encryptor = TDESAlgorithm.CreateEncryptor();
                        Results = Encryptor.TransformFinalBlock( DataToEncrypt, 0, DataToEncrypt.Length );
                    } finally {
                        // Clear the Triple Des and Hashprovider services of any sensitive information
                        TDESAlgorithm.Clear();
                        HashProvider.Clear();
                    }
                }
            }
    
            // Step 6. Return the encrypted string as a base64 encoded string
            return Convert.ToBase64String( Results );
        }
        #endregion
    
        #region "Decrypt"
        // Decrypt using Password from Property (pre-hashed)
        public string Decrypt( string Message ) {
            byte[] Results = null;
            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
            using ( MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider() ) {
                byte[] TDESKey = this.bPassword;
                using ( TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider { Key = TDESKey, Mode = CipherMode.ECB, 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 );
        }
    
        // Decrypt using Password as Byte array
        public string Decrypt( string Message, byte[] Password ) {
            byte[] Results = null;
            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
            using ( MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider() ) {
                byte[] TDESKey = HashProvider.ComputeHash( UTF8.GetBytes( UTF8.GetString( Password ) ) );
                using ( TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider { Key = TDESKey, Mode = CipherMode.ECB, 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 );
        }
    
    
        // Decrypt using Password as string
        public string Decrypt( string Message, string Password ) {
            byte[] Results = null;
            System.Text.UTF8Encoding UTF8 = new System.Text.UTF8Encoding();
    
            // Step 1. We hash the pass phrase using MD5
            // We use the MD5 hash generator as the result is a 128-bit byte array
            // which is a valid length for the Triple DES encoder we use below
            using ( MD5CryptoServiceProvider HashProvider = new MD5CryptoServiceProvider() ) {
                byte[] TDESKey = HashProvider.ComputeHash( UTF8.GetBytes( Password ) );
    
                // Step 2. Create a new TripleDESCryptoServiceProvider object
                // Step 3. Setup the decoder
                using ( TripleDESCryptoServiceProvider TDESAlgorithm = new TripleDESCryptoServiceProvider { Key = TDESKey, Mode = CipherMode.ECB, Padding = PaddingMode.PKCS7 } ) {
    
                    // Step 4. Convert the input string to a byte[]
                    byte[] DataToDecrypt = Convert.FromBase64String( Message );
                    // Step 5. Attempt to decrypt the string
                    try {
                        ICryptoTransform Decryptor = TDESAlgorithm.CreateDecryptor();
                        Results = Decryptor.TransformFinalBlock( DataToDecrypt, 0, DataToDecrypt.Length );
    
                    } finally {
                        // Clear the Triple Des and Hash provider services of any sensitive information
                        TDESAlgorithm.Clear();
                        HashProvider.Clear();
                    }
                }
            }
    
            // Step 6. Return the decrypted string in UTF8 format
            return UTF8.GetString( Results );
        }
    
        #endregion
    }