title: AES cryptography in vb6 and c#
body: <p>I need a .NET <em>(C# ideally)</em> algorithm that will produce the same results as a <code>vb6</code> one I made to encrypt and <code>decrypt</code> binary files. I've been trying to hunt down code for a week now and have had little success. </p>
  
  <p>I started with <a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;821762" rel="nofollow">How to encrypt a string in VB6 decrypt VB.NET</a> but it was only a half solution and it used <code>RC2</code> rather than <code>AES</code>. After some fiddling I got my <code>vb6</code> code to work in <code>AES</code> but I cannot find a way to get <code>c#</code> to produce the same results. I think it has to do with the way I'm making my <code>Key</code> and <code>IV</code>. I've been going over <a href="http://msdn.microsoft.com/en-us/library/93bskf9z.aspx" rel="nofollow">Cryptographic Services</a> my attempts can be broken into two basic types. One where I have tried <code>PasswordDeriveBytes.CryptDeriveKey</code> and trying to make it work with <code>aes</code>. No success at all. And Tries where I tried to mimic it's behavior. Bellow I will post my <code>vb6</code> code and my closest <code>c#</code> attempt. I can't say with 100% certainty that the <code>vb6</code> is perfect so if changes need to be made there I'm open to it. I know there is a way to use p invoke and I know there is a way to make <code>.net dll</code> to be called from my <code>vb apps</code>. I would prefer not to go that way.</p>
  
  <p>VB6 Function </p>
  
  <pre><code>Public Function Crypt_File(PathToSourceFile As String, PathToDestFile As String, Password As String, HowTo As CryptMethod) As Boolean
  Const FName As String = "mdlCryptography.Encrypt_file"
  Dim CryptoContext As Long
  Dim strProvider As String
  Dim HashHnd As Long
  Dim CrypKey As Long
  Dim Step As Integer
  Dim CryptBuff As String
  Dim InFileNum As Long, OutFileNum As Long
  Dim BytesRemaining As Long, CurrentBufferSize  As Long
  Dim MAX_BUFFER_SIZE As Long
  Dim DoCryptFinalise As Long
  Dim Buff As String
  On Error GoTo Trap:
      Step = 10
      Crypt_File = False
      If PathToSourceFile = PathToDestFile Then '
          Err.Raise 334, FName, "Sourse and Dest Path are the same"
      End If
      MAX_BUFFER_SIZE = (2 ^ 20) * 100 '100 MB
      Buff = vbNullChar
      strProvider = MS_ENH_RSA_AES_PROV_A &amp; vbNullChar
      If Not CBool(CryptAcquireContext(CryptoContext, ByVal Buff, ByVal strProvider, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) Then
          Err.Raise 33410, FName, "Unable to Acquire Context: " &amp; MS_ENH_RSA_AES_PROV_A
      End If
  
      If Not CBool(CryptCreateHash(CryptoContext, CALG_SHA_256, ByVal 0&amp;, ByVal 0&amp;, HashHnd)) Then
          Err.Raise 33420, FName, "Unable to Create a hash object. " &amp; MS_ENH_RSA_AES_PROV_A
      End If
  
      If Not CBool(CryptHashData(HashHnd, Password, Len(Password), ByVal 0&amp;)) Then
          Err.Raise 33430, FName, "Unable to Hash password. "
      End If
  
      If Not CBool(CryptDeriveKey(CryptoContext, CALG_AES_256, HashHnd, ByVal CRYPT_NO_SALT, CrypKey)) Then
          Err.Raise 33440, FName, "Unable to Derive Key. "
      End If
      'Clear HashHnd
      If HashHnd &lt;&gt; 0 Then
          Call CryptDestroyHash(HashHnd)
      End If
      HashHnd = 0
  
      'Prep Data For encryption
      DoCryptFinalise = 0
      InFileNum = FreeFile
      Step = 20
      Open PathToSourceFile For Binary Access Read As #InFileNum
      If LenB(Dir$(PathToDestFile)) &gt; 0 Then
          Kill PathToDestFile
      End If
      OutFileNum = FreeFile
      Step = 25
      Open PathToDestFile For Binary Access Write As #OutFileNum
  
      BytesRemaining = LOF(InFileNum)
      'Loop through File Chunks
      Do While BytesRemaining &gt; 0
  
          If BytesRemaining &gt;= MAX_BUFFER_SIZE Then
              CurrentBufferSize = MAX_BUFFER_SIZE
          Else
              CurrentBufferSize = BytesRemaining
              DoCryptFinalise = 1
          End If
  
          Buff = String$(CurrentBufferSize, vbNullChar)
          Get #InFileNum, , Buff
              If HowTo = CryptMethod.Encrypt Then
                  CryptBuff = EncryptBuffer(CrypKey, DoCryptFinalise, Buff)
              Else
                  CryptBuff = DecryptBuffer(CrypKey, DoCryptFinalise, Buff)
              End If
          Put #OutFileNum, , CryptBuff
  
          BytesRemaining = BytesRemaining - CurrentBufferSize
      Loop
      Close #InFileNum
      Close #OutFileNum
      Crypt_File = True
  
  GoTo Fin
  Trap:
      Crypt_File = False
      If Step = 20 Then
          Close #InFileNum
      End If
      If Step = 25 Then
          Close #InFileNum
          Close #OutFileNum
      End If
      Err.Raise Err.Number, Err.source, Err.Description
  Fin:
  
      If CrypKey &lt;&gt; 0 Then
          Call CryptDestroyKey(CrypKey)
      End If
      If HashHnd &lt;&gt; 0 Then
          Call CryptDestroyHash(HashHnd)
      End If
  End Function
  
  Private Function EncryptBuffer(CrypKey As Long, DoCryptFinalise As Long, Buff As String) As String
  Dim EncDataLength As Long, EnctBuffLen As Long
  Dim CryptBuff As String
  
      EncDataLength = Len(Buff)
      EnctBuffLen = EncDataLength + AES_BLOCK_SIZE
      CryptBuff = String$(EnctBuffLen, vbNullChar)
      LSet CryptBuff = Buff
      If Not CBool(CryptEncrypt(CrypKey, ByVal 0&amp;, ByVal DoCryptFinalise, ByVal 0&amp;, CryptBuff, EncDataLength, EnctBuffLen)) Then
  '        Close #InFileNum
  '        Close #OutFileNum
          Err.Raise 33450, "mdlCryptography.EncryptBuffer", "Encryption Error"
      End If
      EncryptBuffer = Left$(CryptBuff, EncDataLength)
  End Function
  
  
  Private Function DecryptBuffer(CrypKey As Long, DoCryptFinalise As Long, Buff As String) As String
  Dim EncDataLength As Long
  Dim CryptBuff As String
  
      EncDataLength = Len(Buff)
      CryptBuff = String$(EncDataLength, vbNullChar)
      LSet CryptBuff = Buff
      If Not CBool(CryptDecrypt(CrypKey, ByVal 0&amp;, ByVal DoCryptFinalise, ByVal 0&amp;, CryptBuff, EncDataLength)) Then
  '        Close #InFileNum
  '        Close #OutFileNum
          Err.Raise 33450, "mdlCryptography.DecryptBuffer", "Decryption Error"
      End If
      DecryptBuffer = Left$(CryptBuff, EncDataLength)
  End Function
  </code></pre>
  
  <p>c# It's very much unrefined</p>
  
  <pre><code>private void Crypt(bool DoEn)
  {
      int Rfc2898KeygenIterations = 100;
      int AesKeySizeInBits = 128;
      byte[] rawPlaintext ;//= System.Text.Encoding.Unicode.GetBytes("This is all clear now!");
      byte[] cipherText = null;
      byte[] plainText = null;
  
      using (Aes aes = new AesManaged())
      {
  
          int KeyStrengthInBytes = aes.KeySize / 8;
  
          SHA256 MySHA = new SHA256Cng();
          MySHA.Initialize();
          plainText = Encoding.ASCII.GetBytes(txtPassword.Text);
          aes.Key = MySHA.ComputeHash(plainText );
          aes.IV =  Encoding.ASCII.GetBytes("0000000000000000");
          if (DoEn)
          {
              //using (FileStream fs = new FileStream(txtOut.Text,FileMode.CreateNew ))
              using (MemoryStream ms = new MemoryStream())
              {
                  using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
                  {
                      //using (StreamReader myFile = new StreamReader(txtIn.Text))
                      //{
                      //    rawPlaintext = System.Text.Encoding.ASCII.GetBytes(myFile.ReadToEnd());
                          rawPlaintext = File.ReadAllBytes(txtIn.Text);
                          cs.Write(rawPlaintext, 0, rawPlaintext.Length);
  
                      //}
                  }
                  cipherText = ms.ToArray();
                  File.WriteAllBytes(txtOut.Text, cipherText);
              }
          }
          else
          {
              //using (FileStream fs = new FileStream(txtIn.Text, FileMode.CreateNew))
              using (MemoryStream ms = new MemoryStream())
              {
                  using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
                  {
                      //using (StreamReader myFile = new StreamReader(txtOut.Text))
                      //{
                          //string s = myFile.r.ReadToEnd();
                          rawPlaintext = File.ReadAllBytes(txtOut.Text); //System.Text.Encoding.ASCII.GetBytes(s);
                          //cipherText = new int[rawPlaintext.Length];
                          cs.Write(rawPlaintext, 0, rawPlaintext.Length);
                          //cs.Write(cipherText, 0, cipherText.Length);
                      //}
                  }
                  cipherText = ms.ToArray();
                  File.WriteAllBytes(txtIn.Text, cipherText);
              }
          }
      }
      //string s = System.Text.Encoding.ASCII.GetString(plainText);
      //Console.WriteLine(s);
  }
  </code></pre>