Page 1 of 1

Rewrite Rijndael 256 C# Encryption Code in PHP

Posted: Tue Aug 17, 2010 1:01 pm
by Celcius
I have an encryption/decryption algorithm written in C# - I need to be able to produce the same encryption in PHP so I can send the encrypted text over HTTP to be decrypted on the C# side.
Here is the C# code for the encryption.

Code: Select all

    this.m_plainText = string.Empty;
    this.m_passPhrase = "passpharse";
    this.m_saltValue = "saltvalue";
    this.m_hashAlgorithm = "SHA1";
    this.m_passwordIterations = 2;
    this.m_initVector = "1a2b3c4d5e6f7g8h";
    this.m_keySize = 256;

    public string Encrypt()
    {
        string plainText = this.m_plainText;
        string passPhrase = this.m_passPhrase;
        string saltValue = this.m_saltValue;
        string hashAlgorithm = this.m_hashAlgorithm;
        int passwordIterations = this.m_passwordIterations;
        string initVector = this.m_initVector;
        int keySize = this.m_keySize;

        // Convert strings into byte arrays.
        // Let us assume that strings only contain ASCII codes.
        // If strings include Unicode characters, use Unicode, UTF7, or UTF8 
        // encoding.
        byte[] initVectorBytes = Encoding.ASCII.GetBytes(initVector);
        byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);

        // Convert our plaintext into a byte array.
        // Let us assume that plaintext contains UTF8-encoded characters.
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

        // First, we must create a password, from which the key will be derived.
        // This password will be generated from the specified passphrase and 
        // salt value. The password will be created using the specified hash 
        // algorithm. Password creation can be done in several iterations.
        PasswordDeriveBytes password = new PasswordDeriveBytes(
                                                        passPhrase,
                                                        saltValueBytes,
                                                        hashAlgorithm,
                                                        passwordIterations);

        // Use the password to generate pseudo-random bytes for the encryption
        // key. Specify the size of the key in bytes (instead of bits).
        byte[] keyBytes = password.GetBytes(keySize / 8 );

        // Create uninitialized Rijndael encryption object.
        RijndaelManaged symmetricKey = new RijndaelManaged();

        // It is reasonable to set encryption mode to Cipher Block Chaining
        // (CBC). Use default options for other symmetric key parameters.
        symmetricKey.Mode = CipherMode.CBC;

        // Generate encryptor from the existing key bytes and initialization 
        // vector. Key size will be defined based on the number of the key 
        // bytes.
        ICryptoTransform encryptor = symmetricKey.CreateEncryptor(
                                                         keyBytes,
                                                         initVectorBytes);

        // Define memory stream which will be used to hold encrypted data.
        MemoryStream memoryStream = new MemoryStream();

        // Define cryptographic stream (always use Write mode for encryption).
        CryptoStream cryptoStream = new CryptoStream(memoryStream,
                                                     encryptor,
                                                     CryptoStreamMode.Write);
        // Start encrypting.
        cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);

        // Finish encrypting.
        cryptoStream.FlushFinalBlock();

        // Convert our encrypted data from a memory stream into a byte array.
        byte[] cipherTextBytes = memoryStream.ToArray();

        // Close both streams.
        memoryStream.Close();
        cryptoStream.Close();

        // Convert encrypted data into a base64-encoded string.
        string cipherText = Convert.ToBase64String(cipherTextBytes);

        // Return encrypted string.
        return cipherText;
    }
I have some similar PHP code that may help. It doesn't do exactly as needed, but I think it may be a good place to start.

Code: Select all

  <?php

    /*
     * DEFINE CONSTANTS
     */
    $HashPassPhrase = "passpharse";
    $HashSalt = "saltvalue";
    $HashAlgorithm = "SHA1";
    $<span style='color:blue' title='I&#39;m naughty, are you naughty?'>smurf</span> = "2";
    $InitVector = "1a2b3c4d5e6f7g8h";        // Must be 16 bytes
    $keySize = "256";
    
    class Cipher {
        private $securekey, $iv;
        function __construct($textkey) {
            $this->securekey = hash($HashAlgorithm,$textkey,TRUE);
            $this->iv = $InitVector;
        }
        function encrypt($input) {
            return base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->securekey, $input, MCRYPT_MODE_CBC, $this->iv));
        }
        function decrypt($input) {
            return trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $this->securekey, base64_decode($input), MCRYPT_MODE_CBC, $this->iv));
        }
    }

    $cipher = new Cipher($HashPassPhrase);
    
    $encryptedtext = $cipher->encrypt("Text To Encrypt");
    echo "->encrypt = $encryptedtext<br />";
    
    $decryptedtext = $cipher->decrypt($encryptedtext);
    echo "->decrypt = $decryptedtext<br />";
    
    var_dump($cipher);


?>

Re: Rewrite Rijndael 256 C# Encryption Code in PHP

Posted: Tue Aug 17, 2010 3:08 pm
by PHPHorizons
Celcius, I do believe PHP's mcrypt module already has that encryption algorithm. I would highly recommend using mcrypt for this.

http://us2.php.net/mcrypt

Cheers

Re: Rewrite Rijndael 256 C# Encryption Code in PHP

Posted: Tue Aug 17, 2010 4:38 pm
by Celcius
PHPHorizons wrote:Celcius, I do believe PHP's mcrypt module already has that encryption algorithm. I would highly recommend using mcrypt for this.

http://us2.php.net/mcrypt

Cheers
Thanks for the reply PHPHorizons.
I have started working with PHP's mycrypt, and I am so close.

The only thing is I need to recreate this C# function from the code to create the key for the mcrypt_encrypt() function.

Code: Select all

PasswordDeriveBytes password = new PasswordDeriveBytes(
                                                        passPhrase,
                                                        saltValueBytes,
                                                        hashAlgorithm,
                                                        passwordIterations
);
Just to too sure how it functions. I'm thinking something like appending the saltValueBytes onto the passPhrase, then hashing it with the hashAlgorithm of choice over the certain number of iterations.
But I can't seem to reproduce the results.

Re: Rewrite Rijndael 256 C# Encryption Code in PHP

Posted: Tue Aug 17, 2010 7:49 pm
by PHPHorizons
Ah, sorry about that. I thought you were attempting to recreate the actual encryption cipher.

Code: Select all

I need to be able to produce the same encryption in PHP
I'm not good at all with C#, I'll have to defer to someone else to help you on this one.

Re: Rewrite Rijndael 256 C# Encryption Code in PHP

Posted: Wed Aug 18, 2010 7:33 am
by requinix
Celcius wrote:Just to too sure how it functions. I'm thinking something like appending the saltValueBytes onto the passPhrase, then hashing it with the hashAlgorithm of choice over the certain number of iterations.
Actually yeah, that's what PBKDF1 (see RFC 2898 section 5.1) does: passphrase + salt, hashed #iterations times. As in

Code: Select all

md5(md5(md5(md5(/* ... */ ($passPhrase . $saltValueBytes) /* ... */ ))))
Then takes the first X bytes of the output, which can vary so you may have to do some trial-and-error to see what the .NET class does.

Thing is, MSDN says that it uses "an extension" of the standard, which means MS may have created some abomination based off the algorithm.