title: CryptEncrypt/CryptDecrypt WinAPI functions fail when called from vb.net
body: <p>Any help with the following greatly appreciated.....</p>
  
  <p>I have some C++ code I've inherited which decrypts certain structures/byte arrays; I've been trying to write a test program in VB.net which exactly mimics the C++ decryption routine using the same functions, ie. using the WinAPI Crypto calls; in testing, CryptAcquireContext, CryptCreateHash, CryptHashData and CryptDeriveKey all succeed; </p>
  
  <p>However, both the CryptEncrypt and CryptDecrypt functions fail with the Invalid Parameter error, even in the most simple scenario; </p>
  
  <p>(I am aware of the System.Security.Cryptography namespace...and I will resort to this...but the C++ code includes structures with unions, and for testing, it seemed better to try the WinAPI route first)</p>
  
  <p>the sample code is below...I am on Win7x64 sp1, vs 2010 sp1...</p>
  
  <pre><code>Private Sub cmdTest(sender As System.Object, e As System.EventArgs) Handles cmdtest.Click
  
      Dim hCrypt As IntPtr
      Dim hSecretHash, hUserHash As IntPtr
      Dim hSecretKey As IntPtr
      Dim success As Boolean
  
  
      If CryptAcquireContext(hCrypt, vbNullString, MS_DEF_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT) Then
  
          'create hash
          success = CryptCreateHash(hCrypt, CALG_MD5, 0, 0, hSecretHash)
  
          'hash stage 1
          success = CryptHashData(hSecretHash, Encoding.ASCII.GetBytes("yyyyyy"), "xxxxxx".length, 0)
          success = CryptHashData(hSecretHash, Encoding.ASCII.GetBytes("yyyyyy"), "yyyyyy".length, 0)
  
          'derive key
          success = CryptDeriveKey(hCrypt, CALG_RC4, hSecretHash, 0, hSecretKey)
  
          Dim newb(127) As Byte
          Dim teststring As String = "Testing"    
          Dim testbytes() As Byte = Encoding.ASCII.GetBytes(teststring)   
          Buffer.BlockCopy(testbytes, 0, newb, 0, testbytes.Length)
  
      Dim inputlength As UShort = Convert.ToUInt16(testbytes.Length)
          Dim newblength As UShort = CUShort(newb.Length)
          Dim bufferlength As UShort = newblength
  
  
      '---------------BOTH THESE FAIL (all above OK)
          success = CryptEncrypt(hSecretKey, 0, True, 0, newb, newblength, inputlength)
          success = CryptDecrypt(hSecretKey, 0, True, 0, newb, newblength)
      '--------------------------------------------
  
  
          'Destroy the user keycode
          CryptDestroyHash(hUserHash)
  
          'Destroy the secret key
          CryptDestroyKey(hSecretKey)
          CryptDestroyHash(hSecretHash)
  
          'Release the provider
          CryptReleaseContext(hCrypt, 0)
  
      End If
  
  End Sub
  
  Public Const ALG_CLASS_DATA_ENCRYPT As Int32 = 24576
  Public Const ALG_CLASS_HASH As Int32 = 32768
  Public Const ALG_TYPE_ANY As Int32 = 0
  Public Const ALG_SID_RC4 As Int32 = 1
  Public Const ALG_SID_RC2 As Int32 = 2
  Public Const ALG_SID_MD5 As Int32 = 3
  Public Const ALG_SID_SHA1 As Int32 = 4
  Public Const ALG_SID_MAC As Int32 = 5
  Public Const ALG_SID_HMAC As Int32 = 9
  Public Const ALG_TYPE_BLOCK As Int32 = 1536
  Public Const ALG_TYPE_STREAM As Int32 = 2048
  
  Public Const CALG_MD5 As Int32 = ALG_CLASS_HASH + ALG_TYPE_ANY + ALG_SID_MD5
  Public Const CALG_RC2 As Int32 = ALG_CLASS_DATA_ENCRYPT + ALG_TYPE_BLOCK + ALG_SID_RC2
  Public Const CALG_RC4 As Int32 = ALG_CLASS_DATA_ENCRYPT + ALG_TYPE_STREAM + ALG_SID_RC4
  Public Const CALG_SHA1 As Int32 = ALG_CLASS_HASH + ALG_TYPE_ANY + ALG_SID_SHA1
  Public Const CALG_MAC As Int32 = ALG_CLASS_HASH + ALG_TYPE_ANY + ALG_SID_MAC
  Public Const CALG_HMAC As Int32 = ALG_CLASS_HASH + ALG_TYPE_ANY + ALG_SID_HMAC
  
  Public Const PROV_RSA_FULL As Int32 = &amp;H1
  Public Const CRYPT_VERIFYCONTEXT As Int32 = &amp;HF0000000
  
  Public Const HP_ALGID As Int32 = 1
  Public Const HP_HASHVAL As Int32 = 2
  Public Const HP_HASHSIZE As Int32 = 4
  Public Const HP_HMAC_INFO As Int32 = 5
  
  Public Const MS_DEF_PROV As String = "Microsoft Base Cryptographic Provider v1.0"
  
  'Imported Functions:
  &lt;DllImport("advapi32.dll", CharSet:=CharSet.Auto, SetLastError:=True)&gt; _
      Public Shared Function CryptAcquireContext( _
          ByRef hProv As IntPtr, _
          ByVal pszContainer As String, _
          ByVal pszProvider As String, _
          ByVal dwProvType As Int32, _
          ByVal dwFlags As Int32 _
      ) As Boolean
      End Function
  
  &lt;DllImport("advapi32.dll", SetLastError:=True)&gt;
      Public Shared Function CryptEncrypt( _
          ByVal hKey As IntPtr, _
          ByVal hHash As IntPtr, _
          ByVal Final As Boolean, _
          ByVal dwFlags As UShort, _
          pbData() As Byte, _
          pdwDataLen As UShort, _
          ByVal dwBufLen As UShort) As Boolean
      End Function
  
  &lt;DllImport("advapi32.dll", SetLastError:=True, CharSet:=CharSet.Unicode)&gt;
      Public Shared Function CryptDecrypt( _
          ByVal hKey As IntPtr, _
          ByVal hHash As IntPtr, _
          ByVal Final As Boolean, _
          ByVal dwFlags As UShort, _
          pbData() As Byte, _
          pdwDataLen As UShort _
      ) As Boolean
      End Function
  
  &lt;DllImport("advapi32.dll", SetLastError:=True)&gt; _
      Public Shared Function CryptCreateHash( _
          ByVal hProv As IntPtr, _
          ByVal Algid As Int32, _
          ByVal hKey As IntPtr, _
          ByVal dwFlags As Int32, _
          ByRef phHash As IntPtr _
      ) As Boolean
      End Function
  
  &lt;DllImport("advapi32.dll", SetLastError:=True)&gt; _
      Public Shared Function CryptDestroyHash( _
          ByVal hHash As IntPtr _
      ) As Boolean
      End Function
  
  &lt;DllImport("advapi32.dll", SetLastError:=True)&gt; _
      Public Shared Function CryptHashData( _
          ByVal hHash As IntPtr, _
          ByVal pbData() As Byte, _
          ByVal dwDataLen As Int32, _
          ByVal dwFlags As Int32 _
      ) As Boolean
      End Function
  
  &lt;DllImport("advapi32.dll", setlasterror:=True)&gt; _
      Public Shared Function CryptDeriveKey( _
          ByVal hProv As IntPtr, _
          ByVal Algid As Integer, _
          ByVal hBaseData As IntPtr, _
          ByVal dwflags As Integer, _
          ByRef phKey As IntPtr) As &lt;MarshalAs(UnmanagedType.Bool)&gt; Boolean
      End Function
  
  &lt;DllImport("advapi32.dll", SetLastError:=True)&gt; _
      Public Shared Function CryptDestroyKey( _
          ByVal hKey As IntPtr _
      ) As Boolean
      End Function
  </code></pre>