Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!

[VB6] HMAC-SHA-256, HMAC-SHA-1 Using Crypto API

XardozCom

New member
Joined
Oct 25, 2013
Messages
7
You demo work great, but when I try to throw my own data at it, I get: ""Failed to determine decoded length, system error ", "System Error 13"

Any Ideas?
 
Last edited:

dilettante

PowerPoster
Joined
Feb 5, 2006
Messages
20,939
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.
 

XardozCom

New member
Joined
Oct 25, 2013
Messages
7
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

This line is expecting CrLf
Code:
Base64Signature = HS256.Encode(bytSignature, edfBase64, efNoFolding)
I was send Lf Only
so the correct command is:
Code:
Base64Signature = HS256.Encode(bytSignature, edfBase64, efLf)
 
Last edited:

dilettante

PowerPoster
Joined
Feb 5, 2006
Messages
20,939
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.
 

XardozCom

New member
Joined
Oct 25, 2013
Messages
7
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:

Schmidt

PowerPoster
Joined
Jun 21, 2013
Messages
4,843
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))
87c9320aa8834dffbf5887046713187a
1411317388
POST
/e/csl/products/update

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
...
Any ideas would be great

Would like to try to reproduce that here - but without *all* the needed Input
(which would include your PrivateKey-String) - this is not possible...

Olaf
 

dilettante

PowerPoster
Joined
Feb 5, 2006
Messages
20,939
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.
 

berrystar

New member
Joined
Dec 10, 2014
Messages
1
Can anyone help me to do an excel function that will take data as string, the key as string to do HMAC(SHA256(Data, Key)? Thanks!
 

dilettante

PowerPoster
Joined
Feb 5, 2006
Messages
20,939
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.
 

MikiSoft

New member
Joined
Jun 6, 2011
Messages
461
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):
View attachment 128337
 
Last edited:

dilettante

PowerPoster
Joined
Feb 5, 2006
Messages
20,939
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:

[tt]<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>[/tt]

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.
 

MikiSoft

New member
Joined
Jun 6, 2011
Messages
461
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:

dilettante

PowerPoster
Joined
Feb 5, 2006
Messages
20,939
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."

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.
 

MikiSoft

New member
Joined
Jun 6, 2011
Messages
461
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:

dilettante

PowerPoster
Joined
Feb 5, 2006
Messages
20,939
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).
 

dilettante

PowerPoster
Joined
Feb 5, 2006
Messages
20,939
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.
 

dilettante

PowerPoster
Joined
Feb 5, 2006
Messages
20,939
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.
 
Top