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?
Printable View
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?
Nevermind, found the answer above!
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.
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:
This line is expecting CrLfCode: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
I was send Lf OnlyCode:Base64Signature = HS256.Encode(bytSignature, edfBase64, efNoFolding)
so the correct command is:
Code:Base64Signature = HS256.Encode(bytSignature, edfBase64, efLf)
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.
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
Any ideas would be greatCode: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
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.
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!
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.
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):
Attachment 128337
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:
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
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.
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:That is skipped because blnIsWinXP is set to False, but I've removed that check there and it works now as it should.Code:If blnIsWinXP And (Format = edfHexRaw) Then
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
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."
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.
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.
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).
OK, Thx!
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.
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.
Well, I've got a report for HS512 class on Windows 8.1 64-bit that this error has shown:
Attachment 134197
And this is the code which is calling the class:What it could be, how to solve it? On my Windows 7 32-bit it's working perfectly though.Code:With hs5
.InitHmac .ToUTF8(server_seed)
roll_hash = .Encode(.HmacSha512(.ToUTF8("1-" & i)))
End With
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?
Odd.
I just tried the demo program on a Windows 10 x64 system and it works fine there.
https://rcpmag.com/articles/2016/01/...-deadline.aspx
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.Quote:
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.
I can't get the HS256 class working with Windows 10 x64 Excel. All the "Declare Kernal32" functions are red and I get the following error:
Attachment 141555
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.
See PtrSafe <keyword>
I don't have 64-bit Excel to test with.
Hi, dilettante
First of all thank you for the project sample, i have problem using this class to my case.
i have this this data:
Data: hypermart1468914526
Key: a4f6bf89b2a85781b7c1cab997b7ee0c89be03f7ac6ef29b63a45d07253cc401
i have tested in http://codebeautify.org/hmac-generator with HMAC-SHA256 and the result was correct.
How i implement this with your class.
Thank you
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
i realize that the msgbox line was the cause why the result always incorrect, after removing edfBase64 and efNoFolding the result was correctCode: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
Another version that might work better in some scenarios. It only uses the default Base Provider.
However note that this might only work on newer versions of Windows. See Microsoft Base Cryptographic Provider:
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.Quote:
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.
Tested and works on Windows 10 1709 and on Windows Home Server 2011 SP 1 (basically the Windows 7 codebase).
All 7 cases in HS512 Demo 1-2 Base.zip seem to work fine on Windows Server 2013 here.
cheers,
</wqw>
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.
Prehash string:
1522000342.391POST/orders{"price":“1.0”,“size”:“1.0”,“side”:“buy”,“product_id”:“BTC-USD”}
Secret key:
D1/0wNj3wsKg8XcTs4KCfZUVzsHXIOW7w38Moj+YximHA5VQS7zAG47bgNSNGIGtFtYQ0vei2JiSPvX3JkBsA==
How to validate the Signature ? I am using below php code:
PHP Code:
function dec_enc($action, $string) {
$output = false;
$encrypt_method = "AES-256-CBC";
$secret_key = 'This is my secret key';
$secret_iv = 'This is my secret iv';
// hash
$key = hash('sha256', $secret_key);
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
if( $action == 'encrypt' ) {
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
}
else if( $action == 'decrypt' ){
$output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv);
}
return $output;
}
what about CryptBinaryToStringA sha512?
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 ?
You can copy the PtrSafe API declares from WinXP compatible HMAC codebank submission which is x64 compatible.
In x64 version of the OS the handles are 64-bit too i.e. must use LongPtr parameters *and* variables for hKey, hHash, hProv, etc.
cheers,
</wqw>