Rewrite Rijndael 256 C# Encryption Code in PHP

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
Celcius
Forum Newbie
Posts: 3
Joined: Tue Aug 17, 2010 12:22 pm

Rewrite Rijndael 256 C# Encryption Code in PHP

Post 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);


?>
Last edited by Weirdan on Wed Aug 18, 2010 11:42 am, edited 1 time in total.
Reason: fixed smilies, switched syntax highlighting to csharp
User avatar
PHPHorizons
Forum Contributor
Posts: 175
Joined: Mon Sep 14, 2009 11:38 pm

Re: Rewrite Rijndael 256 C# Encryption Code in PHP

Post 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
Celcius
Forum Newbie
Posts: 3
Joined: Tue Aug 17, 2010 12:22 pm

Re: Rewrite Rijndael 256 C# Encryption Code in PHP

Post 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.
User avatar
PHPHorizons
Forum Contributor
Posts: 175
Joined: Mon Sep 14, 2009 11:38 pm

Re: Rewrite Rijndael 256 C# Encryption Code in PHP

Post 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.
User avatar
requinix
Spammer :|
Posts: 6617
Joined: Wed Oct 15, 2008 2:35 am
Location: WA, USA

Re: Rewrite Rijndael 256 C# Encryption Code in PHP

Post 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.
Post Reply