Использование криптографической библиотеки MS на сервере 2012 - код ошибки CryptCreateHash 87: ERROR_INVALID_PARAMETER

Я пытаюсь разместить веб-приложение в новой среде Windows Server 2012, однако получаю непредвиденную ошибку. Этот код существует в нашей кодовой базе в течение многих лет, и на любой другой платформе проблем не было.

Данный код вызывает функцию CryptCreateHash в advapi32.dll - криптографической библиотеке Microsoft. При вызове функции мне возвращается 0 для обозначения сбоя вызова, впоследствии Err.LastDllError возвращает код ошибки 87, который равен ERROR_INVALID_PARAMETER.

Как я уже говорил, этот код отлично работал в течение многих лет в различных средах, в том числе на тестовой машине Windows Server 2012, используемой разработчиками. Однако, когда я включаю живую среду, в которой также работает Server 2012 (хотя и в несколько более сложном контексте системы с балансировкой нагрузки), я получаю сообщение об ошибке. Ни один из серверов еще не был обновлен до Windows Server 2012 R2, на нем установлена готовая версия ОС.

После создания дескриптора для провайдера Crypt с помощью:

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

Я использую hCryptProv для вызова функции 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

Некоторые примеры данных, передаваемых в метод из реальной и разработанной среды:

Dev:

hCryptProv = 4966968

CALG_MD5 = 32771

hHash = 0

Жить:

hCryptProv = 1587622576

CALG_MD5 = 32771

hHash = 0

Похоже, что оба эти набора параметров в основном идентичны, хотя серверs hCryptProv имеет тенденцию быть намного большим числом (возможно, потому что у этого есть намного больше RAM?).

Я попытался использовать SHA1 вместо MD5, но произошла та же ошибка.

Возможно, это проблема 32/64 бит, предполагая, что advapi32.dll является 32-битной?

Любые предложения будут оценены, спасибо.

РЕДАКТИРОВАТЬ:

Прототипы по запросу:

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

Я играл с типом данныхphProvРанее это было Integer, я еще не тестировал с помощью IntPtr. Я пытался использовать ULong, потому что это какHCRYPTPROV тип данных определен в документах MSDN.

typedef ULONG_PTR HCRYPTPROV; 

Также вот значения дескриптора, возвращаемого CryptAcquireContext в различных конфигурациях:

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

Это когда я использовал Integer в качестве типа данных, обратите внимание на переполнение в реальном времени.

РЕДАКТИРОВАТЬ 2

Это возможно исправлено. Теперь, когда я вызываю CryptDecrypt, я получаю ошибку -2146893820 (NTE_BAD_LEN). возможно, делать с*pdwDataLen переменная.

Вот определение метода:

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  Boolean
End Function

И звонок:

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

Ответы на вопрос(1)

Ваш ответ на вопрос