Verwenden der MS Crypto Library auf Server 2012 - CryptCreateHash-Fehlercode 87: ERROR_INVALID_PARAMETER

Ich versuche, eine Webanwendung in einer neuen Windows Server 2012-Umgebung zu hosten. Es wird jedoch ein nicht bekannter Fehler angezeigt. Dieser Code existiert seit Jahren in unserer Codebasis und auf keiner anderen Plattform sind Probleme aufgetreten.

Der fragliche Code ruft die CryptCreateHash-Funktion von advapi32.dll - einer Microsoft-Kryptobibliothek - auf. Beim Aufrufen der Funktion wird eine 0 zurückgegeben, um anzuzeigen, dass der Aufruf fehlgeschlagen ist. Anschließend gibt Err.LastDllError den Fehlercode 87 zurück, der ERROR_INVALID_PARAMETER lautet.

Wie ich bereits sagte, funktioniert dieser Code seit vielen Jahren in einer Vielzahl von Umgebungen einwandfrei - einschließlich einer Windows Server 2012-Testmaschine, die von den Entwicklern verwendet wird. Wenn ich jedoch die Live-Umgebung einsetze, in der auch Server 2012 ausgeführt wird (wenn auch in einem etwas komplexeren Kontext eines Systems mit Lastenausgleich), erhalte ich den Fehler. Keiner der Server wurde bisher auf Windows Server 2012 R2 aktualisiert. Es wird die Standardversion des Betriebssystems ausgeführt.

Nachdem Sie ein Handle für den Crypt Provider erstellt haben, verwenden Sie:

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

Ich benutze hCryptProv, um die CryptCreateHas-Funktion aufzurufen.

  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

Ein Beispiel für die Daten, die von Live- und Entwicklungsumgebungen an die Methode übergeben werden:

Dev:
hCryptProv = 4966968
CALG_MD5 = 32771
hHash = 0

Leben:
hCryptProv = 1587622576
CALG_MD5 = 32771
hHash = 0

Es sieht so aus, als ob diese beiden Parametersätze im Wesentlichen identisch sind, obwohl der Wert für hCryptProv des Servers tendenziell viel größer ist (möglicherweise, weil er viel mehr RAM hat?).

Ich habe versucht, SHA1 anstelle von MD5 zu verwenden, aber der gleiche Fehler ist aufgetreten.

Möglicherweise handelt es sich hierbei um ein 32/64-Bit-Problem. Wird davon ausgegangen, dass advapi32.dll 32-Bit ist?

Anregungen wäre dankbar, danke.

BEARBEITEN:

Prototypen nach Wunsch:

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

Ich habe mit dem Datentyp von gespieltphProv, vorher war es Integer, ich bin noch nicht mit IntPtr getestet. Ich habe versucht, ULong zu verwenden, weil das so istHCRYPTPROV Der Datentyp ist in den MSDN-Dokumenten definiert.

typedef ULONG_PTR HCRYPTPROV; 

Hier sind auch die Werte des von CryptAcquireContext in verschiedenen Konfigurationen zurückgegebenen Handles:

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

Dies ist aus, als ich Integer als Datentyp verwendet habe, beachten Sie den Überlauf auf live.

BEARBEITEN 2

Dies ist möglicherweise behoben. Wenn ich jetzt CryptDecrypt anrufe, erhalte ich den Fehler -2146893820 (NTE_BAD_LEN). möglicherweise mit dem zu tun*pdwDataLen Variable.

Hier ist die Methodendefinition:

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

Und der Aufruf:

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

Antworten auf die Frage(1)

Ihre Antwort auf die Frage