Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
Glad you found it. The version lie seems to be a common problem. I guess a lot of people are lying to VB6.exe by setting some "XP compatibility" option though I don't know what they expect that to buy them except trouble.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
Solved
The Encoder was generating a result of: mQIrKnsvUpMQ/rGUe/mAv5xFvpwoqwCRAB1YsYa7YM8=
But the host is calculating/expecting: mz6rcXAtV3Qyx7DqnxQ/0PY8/wj8prf3ON3Dyt22dtk=
I am following the sample project:
Code:
Dim StringToSign As String
StringToSign = signable_string
Dim bytStringToSign() As Byte
bytStringToSign = HS256.ToUTF8(StringToSign)
StringToSign = ""
Dim bytSecretKey() As Byte
bytSecretKey = HS256.ToUTF8(ESL_Settings.PrivateKey)
'Initialize the HMAC with our Key:
HS256.InitHmac bytSecretKey
Erase bytSecretKey
'Create the Signature hash:
Dim bytSignature() As Byte
bytSignature = HS256.HmacSha256(bytStringToSign)
Erase bytStringToSign
'Convert the Signature to Base64:
Dim Base64Signature As String
Base64Signature = HS256.Encode(bytSignature, edfBase64, efNoFolding)
Erase bytSignature
Debug.Print Base64Signature
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
As long as you got what you need, but...
I don't see how that would have made a difference. That only specifies how long runs of Base64 encoded data are to be wrapped/folded. And of course when running on the now unsupported and dead Windows XP there are issues because the efNoFolding values is not supported there.
In any case that would have no bearing on the output of the HmacSha256() method. Surely there was something else going on.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
Well, I guess it did not work.
For some reason it worked once (Or appeared to).
Input string: (Each line ends in a Chr$(10))
Output from Class:
au9MEWefulSThFOdIIzt796TU1uhbeSZWu1NAe6+aac=
Output from Server:
Ig/pGE6kkRC8I370J2OTek3cGVgK5aEoSFGs1jD1FXk=
I tried this VB.Net2008 code and it works, but the project is in VB6
Code:
Public Shared Function HashString(ByVal StringToHash As String, ByVal PrivateKey As String) As String
Dim myEncoder As New System.Text.UTF8Encoding
Dim Key() As Byte = myEncoder.GetBytes(PrivateKey)
Dim Text() As Byte = myEncoder.GetBytes(StringToHash)
Dim myHMACSHA1 As New System.Security.Cryptography.HMACSHA256(Key)
Dim HashCode As Byte() = myHMACSHA1.ComputeHash(Text)
Return Convert.ToBase64String(HashCode)
End Function
Any ideas would be great
Last edited by XardozCom; Oct 19th, 2014 at 12:28 PM.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
Exactly.
This needs its own question thread, as far as I can tell there is some usage error or program bug. Probably related to character encoding or something.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
Post #22 above should have everything you need and more.
First you need to decide what your "string" values really mean since HMACs are created from raw bytes.
So perhaps your Key and/or Data are hex digits? Or maybe they are just printable characters? And if the latter you need to decide whether they need to be converted from Excel VBA's String type strings (i.e. UTF-16LE) to UTF-8 or ANSI or something because UTF-16LE would rarely be used to produce HMACs.
If you only use the ASCII subset of printable characters then ANSI conversion gives the same result as UTF-8 conversion, so that could be a quick and dirty solution (i.e. use the StrConv() function). Or you could call HS256's ToUTF8() method to be sure.
Once you have dealt with how your "string" data needs to be converted to Byte arrays you just call InitHmac() passing your Key and then call HmacSha256() passing your Data and getting back the HMAC value.
Once you have the HMAC value you need to decide how to use it, since it will be binary data. Perhaps you need it converted to hex? You can call Encode() to do that.
Beyond this I suggest you either (1.) get a programmer to help you, or (2.) start a question thread in the Office forum here.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
Please check HMAC-SHA-256 class module, because after I've implemented it in my project, program doesn't act correctly under Windows 8, but under XP it works as it should. To be clear - returned data from your class module is combined with some other data, and it returns expected results when I run program on XP, but on 8 it gives false data and program won't work correctly. Maybe API calls/parameters are different (I think I've read that somewhere regarding CryptoAPI)?
Edit: I see that it has a check for XP, and on Windows 8 it is set as True. Can you fix that? Thanks.
Edit 2: I was talking about HS256 Version 2.2. I've downloaded the latest version and the class won't even intialize (because it's not detecting Windows 8, it tries to initialize with XP parameter):
Last edited by MikiSoft; Jul 12th, 2015 at 12:44 PM.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
The class calls GetVersionEx() to determine the version of Windows in use.
This will always be correct unless a version-lie appcompat shim is being used. However starting in Windows 8.1 (not Windows 8) there is a version-lie that will report that Windows 8 is in use unless overridden using a manifest with a <compatibility/> node containing:
i.e. Windows 8.1 compatibility, or the new value for Windows 10 when running on Windows 10.
So what that means is that there should be no problem because the version is never reported as XP unless you have done something foolish like manually applying an appcompat shim telling Windows to lie to your program and say it is on XP.
How does this happen? Not by magic, but only by your own hand.
There is a lot of VERY BAD ADVICE going around telling people to manually mark VB6.EXE as retarded via Explorer properties ("Run this program in compatibility mode for..."). Don't do this, VB6 is not retarded. It is not only utterly unnecessary, it causes this very kind of problem.
Even when Windows 8.1 lies and tells the program it is running under Windows 8, this should be fine for the purposes of HS256.cls version 2.2 and 2.3 if not earlier versions as well. The Windows version only gets reported as XP if you have done something wrong, i.e. running in an XP compatibility mode.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
I have set VB6.EXE to XP SP3 compatibility mode because I have flicker problem with dragging controls in designer, therefore it's not without a reason. I'm using Windows 8 and still have these problems, so it not like you said.
It still gives me false data under Windows 8.
Edit:
I found the problem - it is in Encode/Decode function on this line of code:
Code:
If blnIsWinXP And (Format = edfHexRaw) Then
That is skipped because blnIsWinXP is set to False, but I've removed that check there and it works now as it should.
Also, in its initialization event I've removed system version check and changed it to much easier trial and error approach:
Code:
Private Sub Class_Initialize()
If CryptAcquireContext(hBaseProvider, _
0&, _
StrPtr(MS_DEFAULT_PROVIDER), _
PROV_RSA_FULL, _
CRYPT_VERIFYCONTEXT Or CRYPT_MACHINE_KEYSET) = 0 Then
Err.Raise vbObjectError Or &HC366&, _
"HS256.Class_Initialize", _
"Failed to obtain CryptoAPI Base context, system error " _
& CStr(Err.LastDllError)
ElseIf CryptAcquireContext(hAdvProvider, _
0&, _
StrPtr(MS_ENH_RSA_AES_PROV), _
PROV_RSA_AES, _
CRYPT_VERIFYCONTEXT Or CRYPT_MACHINE_KEYSET) <> 0 Then Exit Sub
End If
If CryptAcquireContext(hAdvProvider, _
0&, _
StrPtr(MS_ENH_RSA_AES_PROV_XP), _
PROV_RSA_AES, _
CRYPT_VERIFYCONTEXT Or CRYPT_MACHINE_KEYSET) = 0 Then
Err.Raise vbObjectError Or &HC368&, _
"HS256.Class_Initialize", _
"Failed to obtain CryptoAPI RSA AES context, system error " _
& CStr(Err.LastDllError)
End If
End Sub
Last edited by MikiSoft; Jul 13th, 2015 at 03:36 AM.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
Originally Posted by MikiSoft
I have set VB6.EXE to XP SP3 compatibility mode because I have flicker problem with dragging controls in designer, therefore it's not without a reason. I'm using Windows 8 and still have these problems, so it not like you said.
It still gives me false data under Windows 8.
It is exactly as I guessed, you are using a version-lie shim and you shouldn't be. This has nothing at all to do with any "flicker."
Originally Posted by MikiSoft
Edit:
I found the problem - it is in Encode/Decode function on this line of code:
Code:
If blnIsWinXP And (Format = edfHexRaw) Then
That is skipped because blnIsWinXP is set to False, but I've removed that check there and it works now as it should.
Also, in its initialization event I've removed system version check and changed it to much easier trial and error approach:
This is not a fix, but a hack. The version check is there for a reason. Put it back and stop using the version lie. You are only causing yourself more grief and the hack only creates further risk.
If you do this and you have future problems do not expect a response when you ask for help. Your "fix" is a really bad idea.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
It IS flickering when you drag or try to draw a control if you haven't set compatibility to XP SP3... Try it yourself if you don't believe me, it's really hard to design like that.
My solution works now on both Windows XP and 8, because you didn't helped me to solve the problem when compatibility is set, I resorted to the most trivial way.
Last edited by MikiSoft; Jul 13th, 2015 at 03:32 AM.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
He ghetto-rigged the code as he said above.
A better fix if you insist on using the version-lie shim is to first attempt to acquire the MS_ENH_RSA_AES_PROV context, and if that fails attempt to acquire the MS_ENH_RSA_AES_PROV_XP context. If that succeeds set blnIsWinXP = True and continue.
Instead he is sorta kinda doing that but he ripped out the blnIsWinXP checks and is taking the slow boat in other parts of the code.
All of this has a downside. I suspect he now has a lurking time bomb: if his code ever runs on Win 2003 Server it will probably give incorrect results.
There is absolutely no reason to apply an XP version-lie shim to VB6.EXE, and it has nothing to do with working with designers in the IDE. He probably can't mentally separate that from the appcompat shim that disables Aero (a.k.a. desktop composition).
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
An update to HS256:
This is mostly minor general cleanup, but it also revisits version sniffing to get past any usage of version-lie appcompat shims. It also improves the logic for dealing with "problem child" OSs (Windoww XP, Windows Server 2003) even though these are unsupported OSs I should really just ignore.
The Excel demo is also updated in this attachment.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
HMAC-SHA-512, implemented as HS512.cls:
This was fairly trivial to create from HS256 3.1, requiring only a change in the requested algorithm. It was far more effort just to go in and slap in the test vector "expteced result" values to display.
No Excel demo included, since that requires nothing more than some copy/paste operations. If you need to do this you can open the VB6 files in NotePad if nothing else.
Note:
I have not heavily tested HS512 1.1 or for that matter HS256 3.1, but they seem to be working fine. I think I tried HS256 3.1 on XP SP3 but I can't recall at the moment. Both seem to be working fine on Vista SP2, at least as far as the test vectors go.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
The one who sent me the screenshot from above corrected himself that he's using Windows 8.1 (not 8), so I've corrected that in the above post and searched for that error, and I've found this: http://stackoverflow.com/questions/1...nswer-19965034
Since its' cause is probably that system bug it can't be fixed, eh?
Last edited by MikiSoft; Jan 14th, 2016 at 10:22 AM.
As of Jan. 12, 2016, Windows 8 is now considered to be "unsupported" by Microsoft, meaning the company will no longer issues hotfixes or security updates for the operating system. Exceptions to this policy might be organizations that have purchased Microsoft's "custom support," but that option is thought to be an expensive one, with contracts lasting just a year.
So Windows 8 is dead anyway, but Win8.1 Update 1 (or is it Update 2?) should still be supported for a little while. If somebody reports the bug there is a chance it might get fixed. However they really, really, really want people to move off 8.x OSs entirely so maybe it won't.
Last edited by dilettante; Jan 14th, 2016 at 01:40 PM.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
Originally Posted by dilettante
Odd.
I just tried the demo program on a Windows 10 x64 system and it works fine there.
The HS256 class is not working for me in Windows 10 Excel x64. All the "Declare Kernal32" lines are red and I get an error about 64bit compatibility if I try to create one.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
You will have to go through it and make the necessary changes. Part of the problem with 64-bit Office and later versions of Office in general is that VBA6.5 and VBA7 lose some VB6 compatibility.
Add the PtrSafe decorator to Declare statements, and change the type of pointer and handle arguments from Long to LongPtr.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
That web page sort of sucks.
The "key" value must be entered as printable/typeable text, you can't use a string of hex digits. If you do that it just takes it as text and you get an incorrect HMAC value there.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
Originally Posted by dilettante
That web page sort of sucks.
The "key" value must be entered as printable/typeable text, you can't use a string of hex digits. If you do that it just takes it as text and you get an incorrect HMAC value there.
Here's an example with optional "sucks" mode:
Thank you for you sample dilettante, it works as expected.
here is my code before
Code:
Private Sub Command1_Click()
Dim xKey As String
Dim xData As String
Dim bSig() As Byte
Dim StringToSign() As Byte
Dim secretKey() As Byte
xKey = "a4f6bf89b2a85781b7c1cab997b7ee0c89be03f7ac6ef29b63a45d07253cc401"
xData = "hypermart1468914526"
With hs256
StringToSign = .ToUTF8(xData)
secretKey = .ToUTF8(xKey)
.InitHmac secretKey
Erase secretKey
bSig = .HmacSha256(StringToSign)
Erase StringToSign
MsgBox .Encode(bSig, edfBase64, efNoFolding)
Erase bSig
End With
End Sub
i realize that the msgbox line was the cause why the result always incorrect, after removing edfBase64 and efNoFolding the result was correct
To maintain backward compatibility with earlier versions the new version of the provider retains the version 1.0 designation of the name in Wincrypt.h. However, version 2.0 of this provider is currently shipping. To determine the actual version of the provider in use, call CryptGetProvParam with the dwParam argument set to PP_VERSION. If 0x0200 is returned in pbData, then you have version 2.0.
So while the operations my class performs are working under Windows 10 they may rely on things that are only in version 2.0 of this Provider.
Tested and works on Windows 10 1709 and on Windows Home Server 2011 SP 1 (basically the Windows 7 codebase).
Last edited by dilettante; Mar 3rd, 2018 at 10:55 AM.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
Please help a self-taught VBA user that can’t quite close the knowledge gap and use the Excel class that dilettante provided. Does the HS256 Excel demo from post #59 contain the code necessary for the following problem that I have?
I am trying sign a request for an API. The secret key below is an example. The CB-ACCESS-SIGN header is generated by creating a sha256 HMAC using the base64-decoded secret key on the prehash string and base64-encode the output. “1522000342.391” is the timestamp in UNIX Epoch time.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
Originally Posted by dilettante
You will have to go through it and make the necessary changes. Part of the problem with 64-bit Office and later versions of Office in general is that VBA6.5 and VBA7 lose some VB6 compatibility.
Add the PtrSafe decorator to Declare statements, and change the type of pointer and handle arguments from Long to LongPtr.
Hi.
I've added PtrSafe and changed Long to LongPtr (where necessary) in declarations , but the "HS256 Demo 3-1" does not work. It throws "Failed to import key, system error 87". Would it be possible to amend the HS256 Demo 3-1 to be operative in 64-bit Excel ?
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
Error 87 is "The parameter is incorrect."
I suspect you may have changed some Long arguments to LongPtr where they shouldn't be changed. DWORD is an example of a data type that is still 32 bits on an x64 Windows installation.
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
Originally Posted by dilettante
Error 87 is "The parameter is incorrect."
I suspect you may have changed some Long arguments to LongPtr where they shouldn't be changed. DWORD is an example of a data type that is still 32 bits on an x64 Windows installation.
Dear Dilettante.
I've changed Long to LongPtr where the VBE demands it for successful compilation.
The amended project is at the link: https://drive.google.com/file/d/1va8...ew?usp=sharing
Could you kindly look into it to detect an incorrect thing ?
Re: [VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API
Originally Posted by dilettante
Error 87 is "The parameter is incorrect."
I suspect you may have changed some Long arguments to LongPtr where they shouldn't be changed. DWORD is an example of a data type that is still 32 bits on an x64 Windows installation.
Dear Dilettante
I've changed Long to LongPtr where the VBE demands it for successful compilation. May I send you the amended HmacSha256Demo and ask you to look into it and correct as necessary ?