title: Encrypt in VB.NET and Decrypt in PHP
body: <p>I am trying to write a function in PHP and in VB.NET that uses <a href="https://en.wikipedia.org/wiki/Triple_DES" rel="nofollow">Triple DES</a> 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.</p>
  
  <p>The class I wrote in VB.NET, is as follows and is fully functional as it will encrypt and decrypt its own blocks flawlessly.</p>
  
  <pre><code>    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) &amp; "," &amp; 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, ",") &gt; 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
  </code></pre>
  
  <p>Example usage of the above class</p>
  
  <pre><code>    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)
  </code></pre>
  
  <p>Now I also have the following PHP code which ALSO works (by itself)</p>
  
  <pre><code>    class Cipher {
          private $iv;
          private $securekey;
  
          function __construct($key) {
              $this-&gt;securekey = $key;
          }
  
          function encrypt($string) {
              $this-&gt;iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_3DES, MCRYPT_MODE_CFB),MCRYPT_DEV_RANDOM);
              $encrypted = base64_encode(mcrypt_encrypt(MCRYPT_3DES, $this-&gt;securekey, $string, MCRYPT_MODE_CFB, $this-&gt;iv));
              return base64_encode(base64_encode($this-&gt;iv) . ',' . $encrypted);
          }
  
          function decrypt($string) {
              $decrypt = base64_decode($string);
              if(strpos($decrypt,',') &gt; 0) {
                  $decrypt = explode(',', $decrypt);
                  $this-&gt;iv = base64_decode($decrypt[0]);
                  return trim(mcrypt_decrypt(MCRYPT_3DES, $this-&gt;securekey, base64_decode($decrypt[1]), MCRYPT_MODE_CFB, $this-&gt;iv));
              } else {
                  return false;
              }
          }
      }
  </code></pre>
  
  <p>PHP Example Usage</p>
  
  <pre><code>    $c = new Cipher("12345");
      $encrypted = $c-&gt;encrypt("hello");
      echo 'Encrypted: ' . $encrypted . '&lt;br /&gt;';
  
      $decrypted = $c-&gt;decrypt($encrypted);
      echo 'Decrypted: ' . $decrypted . '&lt;br /&gt;';
  
      $vb = "MwBOAEoAOQBjAEgAcQAyAC8ASABzAD0ALABmAEUAOQBaAHYAVwBzAFUAYQB3AFYARwBGAHUANABLAGUAVgB3AFcAaABRAD0APQA=";
      echo 'VB.NET Dec: ' . $c-&gt;decrypt($vb);
  </code></pre>
  
  <p>What I have included above in the PHP usage, is the <a href="http://en.wikipedia.org/wiki/Base64" rel="nofollow">Base64</a> string made with VB.NET that decodes PERFECTLY in VB.NET as the variable $vb.</p>
  
  <p>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 <a href="https://en.wikipedia.org/wiki/Advanced_Encryption_Standard" rel="nofollow">Rijndael</a>, or explore other cipher methods, as this one is well established that works across multiple devices natively (iOS, Android, Windows, Linux, etc.).</p>