-
Aug 27th, 2014, 01:38 AM
#1
Thread Starter
Frenzied Member
Crypto API giving me unexplained problems.
Ok, so I have this program, just to test my ability to get the Crypto API started, and closed properly. And I'm already having troubles.
Here's my test code.
Code:
Private Declare Function CryptAcquireContext Lib "advapi32.dll" Alias "CryptAcquireContextA" (ByRef phProv As Long, ByVal pszContainer As String, ByVal pszProvider As String, ByVal dwProvType As Long, ByVal dwFlags As Long) As Long
Private Declare Function CryptReleaseContext Lib "advapi32.dll" (ByRef hProv As Long, ByRef dwFlags As Long) As Long
Private Const PROV_RSA_FULL As Long = &H1
Private Const CRYPT_VERIFYCONTEXT As Long = &HF0000000
Private Sub Form_Load()
Dim hProv As Long
Dim RetVal As Long
RetVal = CryptAcquireContext(hProv, vbNullString, "Microsoft Base Cryptographic Provider v1.0", PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)
If RetVal = 0 Then Print "CryptAcquireContext Error: " & CStr(GetLastError)
Print "Crypto Provider Handle: " & CStr(hProv)
RetVal = CryptReleaseContext(hProv, 0)
If RetVal = 0 Then Print "CryptReleaseContext Error: " & CStr(GetLastError)
End Sub
Here's what I'm seeing when running the program.
If there is any error, it should be first relating to CryptAcquireContext, which results in an invalid Crypto Provider Handle (the value 0), which then results in another error when using that handle with CryptReleaseContext. What's happening is the program works PERFECTLY up to the part where there it tries to release that handle, and only THEN there is an error. Releasing something should not be the first time an error appears, since it IS a valid crypto handle, and it's being used for NOTHING ELSE. Therefore it shouldn't be a situation where it can't release it due to it using it for something else.
And the error it generates (error 87) corresponds to the error handle ERROR_INVALID_PARAMETER. This means that one of the parameters I gave it is incorrect. How can it be incorrect. The hProv (Provider Handle) is valid, as it was generated by CryptAcquireContext. And the other parameter for CryptReleaseContext (dwFlags) must be set to 0, as the MSDN page for the function says this about that parameter:
Reserved for future use and must be zero. If dwFlags is not set to zero, this function returns FALSE but the CSP is released.
So I don't see why my code is failing. And since it's failing in the most basic parts of the Crypto API, I fear I may not be able to use it. Anyone who can help me here, please do so.
-
Aug 27th, 2014, 01:49 AM
#2
Re: Crypto API giving me unexplained problems.
You may not be passing 0 to CryptReleaseContext's second parameter since you declared it ByRef. If you were passing a Long with a value of 0, the function would actually be receiving a value equivalent to the address of this Long. You passed 0 as a constant which I would guess is placed into a temporary variable by the VB6 runtime before calling the function hence you may not be passing 0 at all.
Change CryptReleaseContext's second parameter to be passed by value.
-
Aug 27th, 2014, 02:59 AM
#3
Thread Starter
Frenzied Member
Re: Crypto API giving me unexplained problems.
Nevermind. The resource I was using to find the API declarations (API Viewer 2004) has a couple errors in its declaration. It's a 3rd party product that has a lot more functions listed than the official MS API Viewer that comes with VB6 (since there's a lot more API functions now than when VB6 was made). Unfortunately some of them are not correctly declared in this 3rd party software. By trial and error though, I managed to figure out what was wrong. A couple ByRef arguments should have been ByVal instead.
Below is the complete code for my program I made that creates and displays the MD5 hash for the text "This is a test.". You can verify it is correct by typing "This is a test." into the online MD5 hash generating webpage http://md5-hash-online.waraxe.us/ and pressing the "Calculate md5 hash" button.
Code:
Private Declare Function CryptCreateHash Lib "advapi32.dll" (ByVal hProv As Long, ByVal Algid As Long, ByVal hKey As Long, ByVal dwFlags As Long, ByRef phHash As Long) As Long
Private Declare Function CryptHashData Lib "advapi32.dll" (ByVal hHash As Long, ByRef pbData As Byte, ByVal dwDataLen As Long, ByVal dwFlags As Long) As Long
Private Declare Function CryptDestroyHash Lib "advapi32.dll" (ByVal hHash As Long) As Long
Private Declare Function CryptAcquireContext Lib "advapi32.dll" Alias "CryptAcquireContextA" (ByRef phProv As Long, ByVal pszContainer As String, ByVal pszProvider As String, ByVal dwProvType As Long, ByVal dwFlags As Long) As Long
Private Declare Function CryptReleaseContext Lib "advapi32.dll" (ByVal hProv As Long, ByVal dwFlags As Long) As Long
Private Declare Function CryptGetHashParam Lib "advapi32.dll" (ByVal hHash As Long, ByVal dwParam As Long, ByVal pByte As Long, ByRef pdwDataLen As Long, ByVal dwFlags As Long) As Long
Private Declare Function GetLastError Lib "kernel32.dll" () As Long
Private Const PROV_RSA_FULL As Long = &H1
Private Const CRYPT_VERIFYCONTEXT As Long = &HF0000000
Private Const HP_HASHSIZE As Long = &H4
Private Const HP_HASHVAL As Long = &H2
Private Const CALG_MD5 As Long = &H8003&
Private Sub Form_Load()
Dim hProv As Long
Dim hHash As Long
Dim RetVal As Long
Dim DataLen As Long
Dim DataIn() As Byte
Dim HashLen As Long
Dim HashOut() As Byte
Dim n As Long
DataIn() = StrConv("This is a test.", vbFromUnicode)
DataLen = UBound(DataIn) + 1
Form1.Show
Print "Number of Characters in String: " & CStr(DataLen)
Print "Text to Be Hashed: " & StrConv(DataIn, vbUnicode)
RetVal = CryptAcquireContext(hProv, vbNullString, "Microsoft Base Cryptographic Provider v1.0", PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)
If RetVal = 0 Then Print "CryptAcquireContext Error: " & CStr(GetLastError)
Print "Crypto Provider Handle: " & CStr(hProv)
RetVal = CryptCreateHash(hProv, CALG_MD5, 0, 0, hHash)
If RetVal = 0 Then Print "CryptCreateHash Error: " & CStr(GetLastError)
Print "Hash Handle: " & CStr(hHash)
RetVal = CryptHashData(hHash, DataIn(0), DataLen, 0)
If RetVal = 0 Then Print "CryptHashData Error: " & CStr(GetLastError)
RetVal = CryptGetHashParam(hHash, HP_HASHSIZE, VarPtr(HashLen), 4, 0)
If RetVal = 0 Then Print "CryptGetHashParam (HashSize) Error: " & CStr(GetLastError)
Print "Number of Bytes in Hash: " & CStr(HashLen)
ReDim HashOut(HashLen - 1)
RetVal = CryptGetHashParam(hHash, HP_HASHVAL, VarPtr(HashOut(0)), HashLen, 0)
If RetVal = 0 Then Print "CryptGetHashParam (HashValue) Error: " & CStr(GetLastError)
Print "MD5 Hash: ";
For n = 0 To HashLen - 1
Print HexByte(HashOut(n));
Next n
Print ""
RetVal = CryptDestroyHash(hHash)
If RetVal = 0 Then Print "CryptDestroyHash Error: " & CStr(GetLastError)
RetVal = CryptReleaseContext(hProv, 0)
If RetVal = 0 Then Print "CryptReleaseContext Error: " & CStr(GetLastError)
End Sub
Private Function HexByte(ByVal Value As Byte) As String
HexByte = String$(2 - Len(Hex$(Value)), "0") & Hex$(Value)
End Function
Last edited by Ben321; Aug 27th, 2014 at 03:16 AM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|