For some reasons, I have to implement hmac sha256 in VBA from Scratch.
I've written the following code but I'm not getting the correct results (for verification, I'm using the following tables : https://www.rfc-editor.org/rfc/rfc4231#section-4.2)
Here is the code implemented :
In my code, the function Hash which corresponds to SHA256 is used from an external library and works fine (I could check the results). I assume then it's working properly but I'm quite sure the problem is coming from the conversion : Decimal, Hex, Byte... It's not something I master well.
I got the formulae from : https://en.wikipedia.org/wiki/Hash-based_message_authentication_code
Can anyone help please with the following code. What's wrong with this HMAC implementation ?
Thank you in advance.
Option Explicit
Public Sub Main()
'Key declaration
Dim Key As String
Dim KeyBytes() As Byte
'Message declaration
Dim Message As String
Dim MessageBytes() As Byte
'ipad, opad
Dim iPad_() As Byte
Dim oPad_() As Byte
'Size
Dim n As Long
'Output
Dim Result() As Byte
Dim A() As Byte, B() As Byte
n = 64
'Define the key
Key = "123"
KeyBytes = Key 'Convert string to byte
KeyBytes = CompleteKey(KeyBytes, n) 'At this step there are 64 Bytes in the key
'Define the message
Message = "TestMessage"
MessageBytes = Message 'Convert string to byte
'Define ipad, opad
iPad_ = ipad(n)
oPad_ = opad(n)
'Get the XOR operation of the key and ipad
B = XOR_(KeyBytes, iPad_)
'Concatenate the result with the message
B = Concatenate(B, MessageBytes)
'Compute the final hash
A = XOR_(KeyBytes, oPad_)
Result = Hash(Concatenate(A, Hash(B)))
End Sub
Public Function CompleteKey(KeyBytes() As Byte, n As Long) As Byte()
Dim O() As Byte
If UBound(KeyBytes) < n Then
O = KeyBytes
ReDim Preserve O(n - 1)
End If
CompleteKey = O
End Function
Public Function XOR_(Item1() As Byte, Item2() As Byte) As Byte()
Dim i As Long, j As Long
Dim A As String, B As String
Dim Output() As Byte
ReDim Output(UBound(Item2) - 1)
For i = 0 To UBound(Item1) - 1
A = WorksheetFunction.Dec2Bin(Item1(i), 8)
B = WorksheetFunction.Dec2Bin(Item2(i), 8)
Output(i) = WorksheetFunction.Bin2Dec(XorBinary(A, B))
Next i
For j = i To UBound(Item2) - 1
Output(i) = Item2(j)
Next j
XOR_ = Output
End Function
Public Function XorBinary(x As String, y As String) As String
Dim i As Long
Dim n As Long
Dim A As Long
Dim B As Long
Dim C As String
Dim O As String
n = Len(x)
For i = 1 To n
A = CLng(Right(Left(x, i), 1))
B = CLng(Right(Left(y, i), 1))
If A * B = 0 And A + B = 1 Then
C = "1"
Else
C = "0"
End If
O = O & C
Next i
End Function
Public Function ipad(n As Long) As Byte()
Dim S() As Byte
Dim i As Long
ReDim S(n)
For i = 1 To n
S(i) = 36
Next i
ipad = S
End Function
Public Function opad(n As Long) As Byte()
Dim S() As Byte
Dim i As Long
ReDim S(n)
For i = 1 To n
S(i) = 92 '5C
Next i
opad = S
End Function
Public Function Concatenate(A() As Byte, B() As Byte) As Byte()
Dim C() As Byte
Dim i As Long, j As Long
ReDim C(UBound(A) + UBound(B) + 1)
For i = 0 To UBound(A)
C(i) = A(i)
Next i
For j = i To i + UBound(B) - 1
C(j) = B(j - UBound(A) - 1)
Next j
Concatenate = C
End Function