Utilisation de la bibliothèque de chiffrement MS sur le serveur 2012 – Code d’erreur CryptCreateHash 87: ERROR_INVALID_PARAMETER

J’essaie d’héberger une application Web sur un nouvel environnement Windows Server 2012, mais je reçois une erreur sans précédent. Ce code existe dans notre base de code depuis des années et aucun problème n’a été rencontré sur aucune autre plate-forme.

Le code en question appelle la fonction CryptCreateHash de advapi32.dll, une bibliothèque de cryptage Microsoft. Lors de l’appel de la fonction, un 0 indiquant que l’appel a échoué est renvoyé. Err.LastDllError renvoie ensuite le code d’erreur 87, ERROR_INVALID_PARAMETER.

Comme je l’ai dit précédemment, ce code fonctionne parfaitement depuis de nombreuses années sur divers environnements, y compris une machine de test Windows Server 2012 utilisée par les développeurs. Cependant, lorsque je suis placé dans l’environnement en ligne qui exécute également Server 2012 (bien que dans un contexte légèrement plus complexe d’un système à charge équilibrée), je reçois l’erreur. Aucun des deux serveurs n’a encore été mis à jour vers Windows Server 2012 R2, il exécute la version prête à l’emploi du système d’exploitation.

Après avoir créé un descripteur pour le fournisseur Crypt à l’aide de:

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

J’utilise hCryptProv pour appeler la fonction 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.ToSsortingng) End If 

Voici un exemple des données transmises à la méthode à partir d’environnements live et dev:

Dev:
hCryptProv = 4966968
CALG_MD5 = 32771
hHash = 0

Vivre:
hCryptProv = 1587622576
CALG_MD5 = 32771
hHash = 0

Il semble que ces deux jeux de parameters soient fondamentalement identiques, bien que le nombre hCryptProv du serveur ait tendance à être beaucoup plus grand (peut-être parce qu’il a beaucoup plus de RAM?).

J’ai essayé d’utiliser SHA1 au lieu de MD5 mais la même erreur s’est produite.

Peut-être qu’il s’agit d’un problème lié à 32/64 bits, en supposant que le fichier advapi32.dll est en 32 bits?

Toutes les suggestions seraient appréciées, merci.

MODIFIER:

Prototypes à la demande:

 Private Declare Function CryptAcquireContext Lib "advapi32.dll" Alias "CryptAcquireContextA" _ (ByRef phProv As IntPtr, _ ByVal pszContainer As Ssortingng, _ ByVal pszProvider As Ssortingng, _ 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 

J’ai joué avec le type de données de phProv , il était probablement Integer, je n’ai pas encore testé avec IntPtr. J’ai essayé d’utiliser ULong car c’est ainsi que le HCRYPTPROV données HCRYPTPROV est défini dans la documentation MSDN.

 typedef ULONG_PTR HCRYPTPROV; 

Voici également les valeurs du descripteur renvoyé par CryptAcquireContext dans différentes configurations:

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

C’est à partir du moment où j’ai utilisé Integer comme type de données, notez le débordement en direct.

EDIT 2

C’est peut-être corrigé. Maintenant, lorsque j’appelle CryptDecrypt, je reçois l’erreur -2146893820 (NTE_BAD_LEN). éventuellement à faire avec la variable *pdwDataLen .

Voici la définition de la méthode:

 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 Ssortingng, _ ByRef pdwDataLen As Integer) _ As  Boolean End Function 

Et l’appel:

 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.ToSsortingng) End If 

Si vous avez un type ULONG_PTR , il doit être défini comme IntPtr dans .NET. Vous aurez également besoin d’un DllImportAtsortingbute Votre CryptCreateHash devrait être:

 Declare Auto Function CryptCreateHash Lib "advapi32.dll" _ (ByVal hProv As IntPtr, _ ByVal algId As Integer, _ ByVal hKey As IntPtr, _ ByVal dwFlags As Integer, _ ByRef phHast As IntPtr) As  Boolean 

Assurez-vous également que vous avez défini la dernière erreur. En C #, nous utilisons un DllImportAtsortingbute et nous nous assurons que SetLastError=true . Sinon, appeler Marshal.GetLastWin32Error ne Marshal.GetLastWin32Error pas ce qui est attendu.

Mettre à jour

Votre prototype CryptDecrypt doit être:

 Declare Function CryptDecrypt Lib "advapi32.dll" (ByVal hkey As IntPtr, _ ByVal hHash As IntPtr, _  ByVal final As Boolean, _ ByVal flags As Integer, _ ByVal data As Byte(), ByRef dataLen As Integer) As  Boolean 

Vous devrez convertir votre chaîne en un tableau d’octets. Notez également que le paramètre dataLen correspond à la longueur du tampon d’octets, et non à la longueur de la chaîne.

Vous devriez consulter pinvoke.net , qui gère des prototypes et des exemples pour la plupart des appels d’API Windows.