The sequence for hashing is:-
Code: Select all
BCryptOpenAlgorithmProvider
BCryptCreateHash
BCryptHashData
BcryptFinishHash
BCryptDestroyHash
BcryptCloseAlgorithmProvider
So, I went to MSDN and found BCryptHash.
This is what Microsoft had to say for themselves:
So, for a single hash computation it seems that we can use.Performs a single hash computation. This is a convenience function that wraps calls to BCryptCreateHash, BCryptHashData, BCryptFinishHash, and BCryptDestroyHash.
Code: Select all
BCryptOpenAlgorithmProvider
BCryptHash
BcryptCloseAlgorithmProvider
For streaming data from large files we need multiple passes of BCryptHashData so we will still have to use the old method.
At the bottom of the APIs we have 'Requirements'. Flaming Microsoft sneaked it into Windows 10 and did not tell me - one of their CNG fans. They are no longer on my Christmas list. "David". "What?". "They weren't anyway". "Oh yeah, I forgot".
Did anybody here know about this and, if so, why didn't you tell me either? <smile>
Well, needless to say, we will not find BCryptHash in any of the bi files so here is an example of a HMAC and the necessary library load.
I checked the result against SlavaSoft's HashCalc - not that I was questioning Microsoft but I was questioning my libary load - and all is well.
MSDN refers to 'BCRYPT_ALG_HANDLE_HMAC flag'. That should read BCRYPT_ALG_HANDLE_HMAC_FLAG.
Full details here.
Added: I went through the B-Suite and could not find any other sneaky insertions into Windows 10.
Example
Code: Select all
#Include Once "windows.bi"
#Inclib "bcrypt"
#Include Once "win/wincrypt.bi"
#Inclib "crypt32"
Dim As Any Ptr library = Dylibload( "BCrypt.dll" )
If library = 0 Then Print "Failed To load BCrypt.dll" : Sleep : End 1
Dim BCryptHash As Function( As BCRYPT_ALG_HANDLE, As Byte Ptr, As Ulong, As Byte Ptr, As Ulong, As Byte Ptr, As Ulong ) As NTSTATUS
BCryptHash = Dylibsymbol( library, "BCryptHash" )
If BCryptHash = 0 Then Print "Could Not retrieve the entry Point of BCryptHash" : Sleep : End 1
' Parameters
' 1 hAlgorithm
' 2 pbSecret: Pointer to HMAC key
' 3 cbSecret: Length of pbSecret
' 4 pbInput: Pointer to Data to hash
' 5 cbInput: Length of pbInput
' 6 pbOutput: Pointer to Output buffer
' 7 cbOutput: Length of pbOutput
Dim As BCRYPT_ALG_HANDLE Ptr hAlg
Dim As String sHMACKey, sDataToHash
Dim As String*32 sOutput
sHMACKey = "Merry Christmas"
sDataToHash = "FreeBASIC"
' Only three statements needed. Bit naughty Using 32, above And below, but I almost invariably use SHA256.
BcryptOpenAlgorithmprovider @hAlg, Wstr("SHA256"), 0, BCRYPT_ALG_HANDLE_HMAC_FLAG ' We need hAlg
BCryptHash( hAlg, Strptr(sHMACKEY), Len(sHMACKey), Strptr(sDataToHash), Len(sDaTaToHash), Strptr(sOutPut), 32 )
BcryptCloseAlgorithmprovider hAlg, 0
' Convert Output To Hex. I normally stay in Binary mode but I wanted To see what we are getting.
Dim As Dword nlength = Len(sOutPut)*2 + 1 ' Hex length of SHA256 + 1; To accomodate a null terminator
Dim As String shex = Space$( nlength )
' At MSDN nlength 'Out' Is Len(sOutPut) * 2, so
CryptBinaryToString Strptr(sOutPut), Len(sOutPut), CRYPT_STRING_HEXRAW + CRYPT_STRING_NOCRLF, Strptr(shex), @nlength
Print Ucase$( Left$( shex, nlength ) )
Sleep