title: .Net and PHP Rijndael encryption not matching
body: <p>At first i thought it was the padding since mcrypt uses zero padding but i changed the php to use PKCS7 and get the same exact results</p>
  
  <p>Can anyone help? I think it has something to do with the padding in the php</p>
  
  <p>Test output from .Net:</p>
  
  <pre><code>Key: d88f92e4fa27f6d45b49446c7fc76976
  Text: Testing123
  Encrypted: /DMkj7BL9Eu2LMxKhdGT+A==
  Encrypted after base64 decode: ?3$??K?K?,?J???
  Decrypted: Testing123
  </code></pre>
  
  <p>Test output from PHP: </p>
  
  <pre><code>Key: d88f92e4fa27f6d45b49446c7fc76976
  Text: Testing123
  Encrypted: K+ke5FNI5T6F6B/XvDF494+S8538Ze83cFz6v1FE89U=
  Encrypted after base64 decode: +éäSHå&gt;…è×¼1x÷’óüeï7p\ú¿QDóÕ
  Decrypted: Testing123����������������������
  </code></pre>
  
  <p>PHP:</p>
  
  <pre><code>class rijndael{
  var $mcrypt_cipher = MCRYPT_RIJNDAEL_256;
  var $mcrypt_mode = MCRYPT_MODE_CBC;
  function decrypt($pass, $encrypted)
  {
      $encrypted = base64_decode($encrypted);
      $key = $this-&gt;getkey($pass);
      $iv = $this-&gt;getiv($pass);
      $decrypted = mcrypt_decrypt($this-&gt;mcrypt_cipher, $key, $encrypted, $this-&gt;mcrypt_mode, $iv);
  
      $block = mcrypt_get_block_size($this-&gt;mcrypt_cipher, $this-&gt;mcrypt_mode);
      $pad = ord($decrypted[($len = strlen($decrypted)) - 1]);
      return substr($decrypted, 0, strlen($decrypted) - $pad);
  
  }
  function encrypt($pass, $decrypted)
  {
      $key = $this-&gt;getkey($pass);
      $iv = $this-&gt;getiv($pass);
      $block = mcrypt_get_block_size($this-&gt;mcrypt_cipher, $this-&gt;mcrypt_mode);
      $pad = $block - (strlen($str) % $block);
      $str .= str_repeat(chr($pad), $pad);
      $encrypted = mcrypt_encrypt($this-&gt;mcrypt_cipher, $key, $decrypted, $this-&gt;mcrypt_mode, $iv);
      return base64_encode($encrypted);
  }
  function getkey($passphrase)
  {
      $L1 = base64_encode(hash("sha256", $passphrase, true));
      $L2 = $passphrase.$L1;
      return hash("sha256", $L2, true);
  }
  function getiv($passphrase)
  {
      $L1 = base64_encode(md5($passphrase));
      $L2 = $passphrase.$L1;
      return md5($L2);
  }
  }
  </code></pre>
  
  <p>VB .Net:</p>
  
  <pre><code>Public Class RijnDael
  
      Public Shared Function Decrypt(ByVal sData As String, ByVal sKey As String)
          Dim bytData() As Byte = Encoding.UTF8.GetBytes(sData)
          Return Decrypt(bytData, sKey)
      End Function
      Public Shared Function Decrypt(ByVal bytData As Byte(), ByVal strPass As String) As Byte()
          Dim bytResult As Byte()
          Using oRM As New System.Security.Cryptography.RijndaelManaged
              oRM.KeySize = 256
              oRM.Key = GeKey(strPass)
              oRM.IV = GetIV(strPass)
              oRM.Mode = CipherMode.CBC
              oRM.Padding = PaddingMode.PKCS7
              Using oMS As New MemoryStream(bytData)
                  Using oCS As New Cryptography.CryptoStream(oMS, oRM.CreateDecryptor, Security.Cryptography.CryptoStreamMode.Read)
                      Dim TempDecryptArr As Byte()
                      ReDim TempDecryptArr(bytData.Length)
                      Dim decryptedByteCount As Integer
                      decryptedByteCount = oCS.Read(TempDecryptArr, 0, bytData.Length)
                      '
                      ReDim bytResult(decryptedByteCount)
                      Array.Copy(TempDecryptArr, bytResult, decryptedByteCount)
                      '
                      oCS.Close()
                  End Using
                  oMS.Close()
              End Using
          End Using
          Return bytResult
      End Function
  
      Public Shared Function Encrypt(ByVal sData As String, ByVal sKey As String)
          Dim bytData() As Byte = Encoding.UTF8.GetBytes(sData)
          Return Encrypt(bytData, sKey)
      End Function
      Public Shared Function Encrypt(ByVal bytData As Byte(), ByVal strPass As String) As Byte()
          Dim bytResult As Byte()
          Using oRM As New Cryptography.RijndaelManaged
              oRM.KeySize = 256
              oRM.Key = GeKey(strPass)
              oRM.IV = GetIV(strPass)
              oRM.Mode = CipherMode.CBC
              oRM.Padding = PaddingMode.PKCS7
              Using oMS As New MemoryStream
                  Using oCS As New Cryptography.CryptoStream(oMS, oRM.CreateEncryptor, Cryptography.CryptoStreamMode.Write)
                      oCS.Write(bytData, 0, bytData.Length)
                      oCS.FlushFinalBlock()
                      bytResult = oMS.ToArray()
                      oCS.Close()
                  End Using
                  oMS.Close()
              End Using
          End Using
          Return bytResult
      End Function
  
      Private Shared Function GeKey(ByVal strPass As String) As Byte()
          Dim bytResult As Byte()
          'Generate a byte array of required length as the encryption key.
          'A SHA256 hash of the passphrase has just the required length. It is used twice in a manner of self-salting.
          Using oSHA256 As New Cryptography.SHA256Managed
              Dim L1 As String = System.Convert.ToBase64String(oSHA256.ComputeHash(Encoding.UTF8.GetBytes(strPass)))
              Dim L2 As String = strPass &amp; L1
              bytResult = oSHA256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(L2))
              oSHA256.Clear()
          End Using
          Return bytResult
      End Function
  
      Private Shared Function GetIV(ByVal strPass As String) As Byte()
          Dim bytResult As Byte()
          'Generate a byte array of required length as the iv.
          'A MD5 hash of the passphrase has just the required length. It is used twice in a manner of self-salting.
          Using oMD5 As New Cryptography.MD5CryptoServiceProvider
              Dim L1 As String = System.Convert.ToBase64String(oMD5.ComputeHash(Encoding.UTF8.GetBytes(strPass)))
              Dim L2 As String = strPass &amp; L1
              bytResult = oMD5.ComputeHash(System.Text.Encoding.UTF8.GetBytes(L2))
              oMD5.Clear()
          End Using
          Return bytResult
      End Function
  
  End Class
  </code></pre>