Usando a biblioteca de criptografia do MS no servidor 2012 - CryptCreateHash error code 87: ERROR_INVALID_PARAMETER

Eu estou tentando hospedar um aplicativo da web em um novo ambiente de servidor do Windows 2012, no entanto, estou recebendo um erro não-reconhecido. Este código existe em nossa base de código há anos e não houve problemas em nenhuma outra plataforma.

O código em questão chama a função CryptCreateHash de advapi32.dll - uma biblioteca de criptografia da Microsoft. Ao chamar a função, retornei um 0 para indicar que a chamada falhou; subsequentemente, Err.LastDllError retorna o código de erro 87, que é ERROR_INVALID_PARAMETER.

Como eu disse antes, esse código funcionou perfeitamente por muitos anos em vários ambientes - incluindo uma máquina de teste do Windows Server 2012 usada pelos desenvolvedores. No entanto, quando colocado no ambiente ao vivo, que também executa o Server 2012 (embora em um contexto um pouco mais complexo de um sistema de carga balanceada), recebo o erro. Nenhum servidor foi atualizado para o Windows Server 2012 R2, ele está executando a versão pronta para uso do sistema operacional.

Depois de criar um identificador para o Crypt Provider usando:

CryptAcquireContext(hCryptProv, vbNullString, SERVICE_PROVIDER, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)

Eu uso hCryptProv para chamar a função CryptCreateHas.

  If CryptCreateHash(hCryptProv, CALG_MD5, 0, 0, hHash) = 0 Then
      Dim _error As Integer = Err.LastDllError
      Throw New CryptoException("Error during CryptCreateHash. Error Code: " & _error.ToString)
  End If

Alguns exemplos dos dados que estão sendo transmitidos para o método a partir de ambientes ao vivo e de desenvolvimento:

Dev:
hCryptProv = 4966968
CALG_MD5 = 32771
hHash = 0

Viver:
hCryptProv = 1587622576
CALG_MD5 = 32771
hHash = 0

Parece que ambos os conjuntos de parâmetros são basicamente idênticos, embora o hCryptProv do servidor tende a ser um número muito maior (possivelmente porque tem muito mais RAM?).

Eu tentei usar SHA1 em vez de MD5, mas o mesmo erro ocorreu.

Possivelmente, este é um problema relacionado com 32/64 bits, presumindo advapi32.dll é 32 bits?

Qualquer sugestão seria apreciada, obrigado.

EDITAR:

Protótipos conforme solicitado:

Private Declare Function CryptAcquireContext Lib "advapi32.dll" Alias "CryptAcquireContextA" _
    (ByRef phProv As IntPtr, _
     ByVal pszContainer As String, _
     ByVal pszProvider As String, _
     ByVal dwProvType As Integer, _
     ByVal dwFlags As Integer) As Integer


Private Declare Function CryptCreateHash Lib "advapi32.dll" _
    (ByVal hProv As IntPtr, _
     ByVal Algid As Integer, _
     ByVal hKey As Integer, _
     ByVal dwFlags As Integer, _
     ByRef phHash As Integer) As Integer

Eu tenho jogado com o tipo de dados dephProv, previosuly foi Integer, ainda estou para testar usando IntPtr. Eu tentei usar ULong porque é assim que oHCRYPTPROV tipo de dados é definido na documentação do MSDN.

typedef ULONG_PTR HCRYPTPROV; 

Também aqui estão os valores do identificador retornado por CryptAcquireContext em várias configurações:

LIVE 32: hCryptProv = 606412672 
LIVE 64: hCryptProv = -1480179632 
LOCAL: hCryptProv = 4966968 
DEV 32: hCryptProv = 99009648 
DEV 64: hCryptProv = 918798256 

Isto é a partir de quando eu usei Integer como o tipo de dados, observe o estouro ao vivo.

EDIT 2

Isso possivelmente é fixo. Agora, quando eu chamo CryptDecrypt, recebo o erro -2146893820 (NTE_BAD_LEN). possivelmente a ver com o*pdwDataLen variável.

Aqui está a definição do método:

Private Declare Function CryptDecrypt Lib "advapi32.dll" _
                              (ByVal hKey As IntPtr, _
                              ByVal hHash As IntPtr, _
                              ByVal Final As Boolean, _
                              ByVal dwFlags As Integer, _
                              ByVal pbData As String, _
                              ByRef pdwDataLen As Integer) _
                            As <MarshalAs(UnmanagedType.Bool)> Boolean
End Function

E a chamada:

lLength = Len(strData)
If CryptDecrypt(_hKey, 0, 1, 0, sTemp, lLength) = False Then
                Dim _error As Integer = Err.LastDllError
                Throw New CryptoException("Error during CryptDecrypt. Error Code: " & _error.ToString)
            End If

questionAnswers(1)

yourAnswerToTheQuestion