From: Steve on
On May 11, 3:59 pm, "Schmidt" <s...(a)online.de> wrote:
> "Steve" <sredm...(a)rfcorp.com> schrieb im Newsbeitragnews:b8281c59-8c79-4011-aff1-bd2b65e49290(a)d27g2000yqc.googlegroups.com...
>
> > I found a pure vb implementation of alot of the .NET features called
> > VBCorLib (available herehttp://sourceforge.net/projects/vbcorlib/).
> > Using this code I was able to replicate what is done with the C#
> > code.
>
> Sounds good.
>
> > Problem I am having now is in figuring out how to extract just
> > the code for the HMAC-SHA1 keyed hash (I can not include
> > the entire library as it is huge).
>
> In this case you perhaps find the following little class useful,
> which I've "thrown together" now - just cleanup my
> coding-style a bit, in case it does not match your taste... ;-)
>
> First, the new Form-Democode, now replicates
> the result of your second given example correctly:
> W8z0Ad5gLsIOYeGz3YnP1XQMapU=
>
> And for the Input-Values of your other given example,
> the ones which (in your opinion) should deliver:
> 1QI77EFgZ+P0KEvHDtBCQi4Jw7A=
> I get here:
> MzFRObwYZoEvp1iQ/Xjx6GS2f9w=
> But I'm near 100% sure, that the above result is the correct one -
> would be good, if you check *all* the Input-Values you've
> posted, if these really match with the ones, which delivered:
> 1QI77EFgZ+P0KEvHDtBCQi4Jw7A=
> on your machine.
>
> '***Into a Form (with a Command1-Button)
> Option Explicit
>
> Private Hash As New cHash
>
> Private Sub Form_Load()
> Dim i&, Key() As Byte
>
>   Debug.Print "Example 0: normal SHA1-HexOutput for a given string: abc"
>   Debug.Print "a9993e364706816aba3e25717850c26c9cd0d89d"
>   Debug.Print Hash.SHA1("abc", True); vbCrLf
>
>   'the next three examples are covering different inputs as described in:
>   'http://csrc.nist.gov/publications/fips/fips198/fips-198a.pdf
>
>   Debug.Print "Example 1: HMAC_SHA1-Output for a Key, 64 Bytes long..."
>   ReDim Key(0 To 63)
>   For i = 0 To 63: Key(i) = i: Next
>   Debug.Print "4f4ca3d5d68ba7cc0a1208c9c61e9c5da0403c0a"
>   Debug.Print Hash.HMAC_SHA1("Sample #1", Key, True); vbCrLf
>
>   Debug.Print "Example 2: HMAC_SHA1-Output for a Key, 20 Bytes long..."
>   Debug.Print "0922d3405faa3d194f82a45830737d5cc6c75d24"
>   Debug.Print Hash.HMAC_SHA1("Sample #2", "0123456789:;<=>?@ABC", True)
>   Debug.Print
>
>   Debug.Print "Example 3: HMAC_SHA1-Output for a Key, 100 Bytes long..."
>   ReDim Key(0 To 99)
>   For i = 0 To 15: Key(&H0 + i) = &H50 + i: Next
>   For i = 0 To 15: Key(&H10 + i) = &H60 + i: Next
>   For i = 0 To 15: Key(&H20 + i) = &H70 + i: Next
>   For i = 0 To 15: Key(&H30 + i) = &H80 + i: Next
>   For i = 0 To 15: Key(&H40 + i) = &H90 + i: Next
>   For i = 0 To 15: Key(&H50 + i) = &HA0 + i: Next
>   For i = 0 To 3: Key(&H60 + i) = &HB0 + i: Next
>   Debug.Print "bcf41eab8bb2d802f3d05caf7cb092ecf8d1a3aa"
>   Debug.Print Hash.HMAC_SHA1("Sample #3", Key, True); vbCrLf
> End Sub
>
> Private Sub Command1_Click()
> Dim txtToken$, txtPlan$, txtClaim$, txtCSR$, txtDate$
> Dim sharedSecretBytes() As Byte, stringToHash As String
> Dim HMACResult() As Byte
>
>     sharedSecretBytes = StrConv("SharedSecretKeyStoredInConfig", _
>                                 vbFromUnicode)
>
>     txtPlan = "16263392"
>     txtClaim = "3278053"
>     txtCSR = "DA3"
>     txtToken = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
>     txtDate = "5/5/2010 13:54"
>     stringToHash = txtPlan + txtClaim + txtCSR + txtToken + txtDate
>
>     HMACResult = Hash.HMAC_SHA1(stringToHash, sharedSecretBytes, False)
>     Debug.Print Hash.Base64Enc(HMACResult)
>
>     sharedSecretBytes = StrConv("", vbFromUnicode)
>
>     txtPlan = "15847812"
>     txtClaim = "3270278"
>     txtCSR = "DA3"
>     txtToken = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
>     txtDate = "5/5/2010 13:54"
>     stringToHash = txtPlan + txtClaim + txtCSR + txtToken + txtDate
>
>     HMACResult = Hash.HMAC_SHA1(stringToHash, sharedSecretBytes, False)
>     Debug.Print Hash.Base64Enc(HMACResult)
> End Sub
>
> '***Into a Class, named cHash (also supporting Base64 now)
> Option Explicit
>
> Private Declare Sub RtlMoveMemory Lib "kernel32" _
>   (Dst As Any, Src As Any, ByVal LenBytes As Long)
>
> Private Const CRYPT_STRING_BASE64  As Long = 1
> Private Const CRYPT_VERIFYCONTEXT = &HF0000000
> Private Const CRYPT_MACHINE_KEYSET = 32
>
> Private Declare Function CryptBinaryToStringW Lib "crypt32" ( _
>    pbBinary As Any, _
>    ByVal cbBinary As Long, _
>    ByVal dwFlags As Long, _
>    ByVal pszString As Long, _
>    pcchString As Long) As Long
>
> Private Declare Function CryptStringToBinaryW Lib "crypt32" ( _
>    ByVal pszString As Long, _
>    ByVal cchString As Long, _
>    ByVal dwFlags As Long, _
>    pbBinary As Any, _
>    pcbBinary As Long, _
>    pdwSkip As Any, _
>    pdwFlags As Any) As Long
>
> Private Declare Function CryptAcquireContextW Lib "advapi32" ( _
>    ByRef phProv As Long, _
>    ByVal pszContainer As Long, _
>    ByVal pszProvider As Long, _
>    ByVal dwProvType As Long, _
>    ByVal dwFlags As Long) As Long
>
> Private Declare Function CryptReleaseContext Lib "advapi32" ( _
>    ByVal hProv As Long, _
>    ByVal dwFlags As Long) As Long
>
> Private Declare Function CryptCreateHash Lib "advapi32" ( _
>    ByVal hProv As Long, _
>    ByVal Algid As Long, _
>    ByVal hKey As Long, _
>    ByVal dwFlags As Long, _
>    ByRef phHash As Long) As Long
>
> Private Declare Function CryptDestroyHash Lib "advapi32" ( _
>    ByVal hHash As Long) As Long
>
> Private Declare Function CryptHashData Lib "advapi32" ( _
>    ByVal hHash As Long, _
>    pbData As Any, _
>    ByVal dwDataLen As Long, _
>    ByVal dwFlags As Long) As Long
>
> Private Declare Function CryptGetHashParam Lib "advapi32" ( _
>    ByVal hHash As Long, _
>    ByVal dwParam As Long, _
>    pbData As Any, _
>    pdwDataLen As Long, _
>    ByVal dwFlags As Long) As Long
>
> Private Const PROV_RSA_FULL = 1
> Private Const PROV_RSA_AES = 24
>
> Private Const ALG_CLASS_HASH = 32768
>
> Private Const ALG_TYPE_ANY = 0
> Private Const ALG_SID_MD2 = 1
> Private Const ALG_SID_MD4 = 2
> Private Const ALG_SID_MD5 = 3
> Private Const ALG_SID_SHA1 = 4
> Private Const ALG_SID_SHA_256 = 12
> Private Const ALG_SID_SHA_384 = 13
> Private Const ALG_SID_SHA_512 = 14
>
> Private Enum HashAlgorithm
>   CALG_MD2 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_MD2)
>   CALG_MD4 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_MD4)
>   CALG_MD5 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_MD5)
>   CALG_SHA1 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_SHA1)
>   CALG_SHA256 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_SHA_256)
>   CALG_SHA384 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_SHA_384)
>   CALG_SHA512 = (ALG_CLASS_HASH Or ALG_TYPE_ANY Or ALG_SID_SHA_512)
> End Enum
>
> Private Const HP_HASHVAL = 2
> Private Const HP_HASHSIZE = 4
>
> Public Function Base64Enc(Data) As String
> Dim B() As Byte, BLen As Long, SLen As Long
>
>   If VarType(Data) = vbString Then
>     B = StrConv(Data, vbFromUnicode)
>   Else
>     B = Data
>   End If
>   BLen = UBound(B) - LBound(B) + 1
>
>   CryptBinaryToStringW B(LBound(B)), BLen, CRYPT_STRING_BASE64, 0, SLen
>
>   Base64Enc = Space$(SLen)
>   CryptBinaryToStringW B(LBound(B)), BLen, CRYPT_STRING_BASE64, _
>                        StrPtr(Base64Enc), SLen
>
>   Base64Enc = Left$(Base64Enc, SLen - 2) 'cut off the vbCrLf at the end
> End Function
>
> Public Function Base64Dec(Base64Str As String, _
>                 Optional ByVal AsByteArr As Boolean)
> Dim B() As Byte, OutLen As Long
>
>   CryptStringToBinaryW StrPtr(Base64Str), Len(Base64Str), _
>        CRYPT_STRING_BASE64, ByVal 0&, OutLen, ByVal 0&, ByVal 0&
>
>   B = vbNullString
>   If OutLen Then
>     ReDim B(OutLen - 1)
>     CryptStringToBinaryW StrPtr(Base64Str), Len(Base64Str), _
>          CRYPT_STRING_BASE64, B(0), OutLen, ByVal 0&, ByVal 0&
>   End If
>
>   If AsByteArr Then
>     Base64Dec = B
>   Else
>     Base64Dec = StrConv(B, vbUnicode)
>   End If
> End Function
>
> Public Function SHA1(Message, Optional ByVal AsHexStr As Boolean)
> Dim Msg() As Byte
>   If VarType(Message) = vbString Then
>     Msg = StrConv(Message, vbFromUnicode)
>   Else
>     Msg = Message
>   End If
>   SHA1 = Hash(Msg, CALG_SHA1, AsHexStr)
> End Function
>
> Public Function SHA256(Message, Optional ByVal AsHexStr As Boolean)
> Dim Msg() As Byte
>   If VarType(Message) = vbString Then
>     Msg = StrConv(Message, vbFromUnicode)
>   Else
>     Msg = Message
>   End If
>   SHA256 = Hash(Msg, CALG_SHA256, AsHexStr)
> End Function
>
> Public Function MD5(Message, Optional ByVal AsHexStr As Boolean)
> Dim Msg() As Byte
>   If VarType(Message) = vbString Then
>     Msg = StrConv(Message, vbFromUnicode)
>   Else
>     Msg = Message
>   End If
>   MD5 = Hash(Msg, CALG_MD5, AsHexStr)
> End Function
>
> Public Function HMAC_SHA1(Message, Key, Optional ByVal AsHexStr As Boolean)
> Dim M() As Byte, K() As Byte
>   If VarType(Message) = vbString Then
>     M = StrConv(Message, vbFromUnicode)
>   Else 'we assume a byte-array now, and provoce an error, if it isn't one
>     M = Message
>   End If
>
>   If VarType(Key) = vbString Then
>     K = StrConv(Key, vbFromUnicode)
>   Else 'we assume a byte-array now, and provoce an error, if it isn't one
>     K = Key
>   End If
>
>   HMAC_SHA1 = HMAC(M, K, CALG_SHA1, AsHexStr)
> End Function
>
> Public Function HMAC_MD5(Message, Key, Optional ByVal AsHexStr As Boolean)
> Dim M() As Byte, K() As Byte
>   If VarType(Message) = vbString Then
>     M = StrConv(Message, vbFromUnicode)
>   Else 'we assume a byte-array now, and provoce an error, if it isn't one
>     M = Message
>   End If
>
>   If VarType(Key) = vbString Then
>     K = StrConv(Key, vbFromUnicode)
>   Else 'we assume a byte-array now, and provoce an error, if it isn't one
>     K = Key
>   End If
>
>   HMAC_MD5 = HMAC(M, K, CALG_MD5, AsHexStr)
> End Function
>
> Private Function Hash(Msg() As Byte, ByVal Algo As HashAlgorithm, _
>                       ByVal AsHexStr As Boolean)
> Dim i As Long, hCtx As Long, hHash As Long, lLen As Long
> Dim Prov As Long, Arr() As Byte
>
>   'PROV_RSA_AES is needed for SHA256 and above (needs a WinOS >= XP-SP3)
>   Prov = IIf(Algo > CALG_SHA1, PROV_RSA_AES, PROV_RSA_FULL)
>
>   If CryptAcquireContextW(hCtx, 0, 0, Prov, _
>                           CRYPT_VERIFYCONTEXT Or CRYPT_MACHINE_KEYSET) Then
>
>     If CryptCreateHash(hCtx, Algo, 0, 0, hHash) Then
>
>       If CryptHashData(hHash, Msg(0), UBound(Msg) + 1, 0) Then
>
>         If CryptGetHashParam(hHash, HP_HASHSIZE, lLen, 4, 0) Then
>
>           ReDim Arr(0 To lLen - 1) ' Initialize the buffer
> ...
>
> read more »

WOW! thanks Olaf...that worked perfectly. I can not tell you how
greatfull I am.

As for the one example where you got a different value than I thought
should be correct...I had somehow managed to put the wrong result in
the code comments. That said the results you list in your post are
also not correct (nor is it the value returned by your code). Not
sure where I got the value I came up with but maybe my post, that had
these two sets of data to be hashed, contained a Type-O.

Here are the correct values for both test along with the correct
(matches the results from the C# class) results.
'Example using no key value
txtKey = ""
txtToken = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
txtPlan = "15847812"
txtClaim = "3270278"
txtCSR = "DA3"
txtDate = "5/5/2010 13:54"
' Result of C# HMACSHA1 class = "hnf6YssSGCfkSyb546ONDI8xwZs="

'Example using test key value
txtKey = "SharedSecretKeyStoredInConfig"
txtToken = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
txtPlan = "16263392"
txtClaim = "3278053"
txtCSR = "DA3"
txtDate = "5/5/2010 13:54"
' Result of C# HMACSHA1 class = "W8z0Ad5gLsIOYeGz3YnP1XQMapU="

Again thanks so much for your help

Steve
From: Schmidt on

"Steve" <sredmyer(a)rfcorp.com> schrieb im Newsbeitrag
news:104c74b7-beef-4565-99ec-87e32f897ce5(a)r11g2000yqa.googlegroups.com...

> Here are the correct values for both test along with the correct
> (matches the results from the C# class) results.
> 'Example using no key value
> txtKey = ""
> txtToken = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
> txtPlan = "15847812"
> txtClaim = "3270278"
> txtCSR = "DA3"
> txtDate = "5/5/2010 13:54"
>' Result of C# HMACSHA1 class = "hnf6YssSGCfkSyb546ONDI8xwZs="
>
> 'Example using test key value
> txtKey = "SharedSecretKeyStoredInConfig"
> txtToken = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
> txtPlan = "16263392"
> txtClaim = "3278053"
> txtCSR = "DA3"
> txtDate = "5/5/2010 13:54"
>' Result of C# HMACSHA1 class = "W8z0Ad5gLsIOYeGz3YnP1XQMapU="

As said, the second one of your above examples already works
with the code I've posted - and the first one will now also deliver
the correct result, if you pass the routines *not* an empty
String in txtKey, but use the same Key as in the already working
example again: txtKey = "SharedSecretKeyStoredInConfig"

So I assume, that the HMACSHA1-class, which the C#-code
is using, will get initialized with the Key once (at construction
time) - and after that the class will get passed only different
Message-Content, to produce the different HMAC-results.

To achieve the same effect with my code, you should
define the (currently local) Variable:
sharedSecretBytes() As Byte
globally - and re-initialize it only at occassions, where
KeyChanges are required (whoever initiates these).
And an empty Key for the sharedSecret does not really make
sense in such scenarios, but I verified my "wrong" Empty-Key-
result: MzFRObwYZoEvp1iQ/Xjx6GS2f9w=
already against ".NET-code" - and got the same
result there.

'Ok, here are the three variants again in the Command1-routine:
'
Private Sub Command1_Click()
Dim txtToken$, txtPlan$, txtClaim$, txtCSR$, txtDate$
Dim sharedSecretBytes() As Byte, stringToHash As String
Dim HMACResult() As Byte

'Example 1, which should deliver:
'W8z0Ad5gLsIOYeGz3YnP1XQMapU=
sharedSecretBytes = StrConv("SharedSecretKeyStoredInConfig", _
vbFromUnicode)

txtPlan = "16263392"
txtClaim = "3278053"
txtCSR = "DA3"
txtToken = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
txtDate = "5/5/2010 13:54"
stringToHash = txtPlan + txtClaim + txtCSR + txtToken + txtDate

HMACResult = Hash.HMAC_SHA1(stringToHash, sharedSecretBytes, False)
Debug.Print Hash.Base64Enc(HMACResult)

'Example 2 (with an empty String as the Key) ... result should be:
'MzFRObwYZoEvp1iQ/Xjx6GS2f9w=
sharedSecretBytes = StrConv("", vbFromUnicode)

txtPlan = "15847812"
txtClaim = "3270278"
txtCSR = "DA3"
txtToken = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
txtDate = "5/5/2010 13:54"
stringToHash = txtPlan + txtClaim + txtCSR + txtToken + txtDate

HMACResult = Hash.HMAC_SHA1(stringToHash, sharedSecretBytes, False)
Debug.Print Hash.Base64Enc(HMACResult)

'Example 3 (with the same Input as Example 2, but using the
'same Key as in Example 1 now) ... should deliver:
'hnf6YssSGCfkSyb546ONDI8xwZs=
sharedSecretBytes = StrConv("SharedSecretKeyStoredInConfig", _
vbFromUnicode)

txtPlan = "15847812"
txtClaim = "3270278"
txtCSR = "DA3"
txtToken = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
txtDate = "5/5/2010 13:54"
stringToHash = txtPlan + txtClaim + txtCSR + txtToken + txtDate

HMACResult = Hash.HMAC_SHA1(stringToHash, sharedSecretBytes, False)
Debug.Print Hash.Base64Enc(HMACResult)
End Sub

Olaf


From: Steve on
On May 12, 9:51 am, "Schmidt" <s...(a)online.de> wrote:
> "Steve" <sredm...(a)rfcorp.com> schrieb im Newsbeitragnews:104c74b7-beef-4565-99ec-87e32f897ce5(a)r11g2000yqa.googlegroups.com...
>
>
>
>
>
> > Here are the correct values for both test along with the correct
> > (matches the results from the C# class) results.
> >   'Example using no key value
> >    txtKey = ""
> >    txtToken = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
> >    txtPlan = "15847812"
> >    txtClaim = "3270278"
> >    txtCSR = "DA3"
> >    txtDate = "5/5/2010 13:54"
> >'    Result of C# HMACSHA1 class =  "hnf6YssSGCfkSyb546ONDI8xwZs="
>
> >    'Example using test key value
> >    txtKey = "SharedSecretKeyStoredInConfig"
> >    txtToken = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
> >    txtPlan = "16263392"
> >    txtClaim = "3278053"
> >    txtCSR = "DA3"
> >    txtDate = "5/5/2010 13:54"
> >'    Result of C# HMACSHA1 class =  "W8z0Ad5gLsIOYeGz3YnP1XQMapU="
>
> As said, the second one of your above examples already works
> with the code I've posted - and the first one will now also deliver
> the correct result, if you pass the routines *not* an empty
> String in txtKey, but use the same Key as in the already working
> example again:  txtKey = "SharedSecretKeyStoredInConfig"
>
> So I assume, that the HMACSHA1-class, which the C#-code
> is using, will get initialized with the Key once (at construction
> time) - and after that the class will get passed only different
> Message-Content, to produce the different HMAC-results.
>
> To achieve the same effect with my code, you should
> define the (currently local) Variable:
> sharedSecretBytes() As Byte
> globally - and re-initialize it only at occassions, where
> KeyChanges are required (whoever initiates these).
> And an empty Key for the sharedSecret does not really make
> sense in such scenarios, but I verified my "wrong" Empty-Key-
> result: MzFRObwYZoEvp1iQ/Xjx6GS2f9w=
> already against ".NET-code" - and got the same
> result there.
>
> 'Ok, here are the three variants again in the Command1-routine:
> '
> Private Sub Command1_Click()
> Dim txtToken$, txtPlan$, txtClaim$, txtCSR$, txtDate$
> Dim sharedSecretBytes() As Byte, stringToHash As String
> Dim HMACResult() As Byte
>
>   'Example 1, which should deliver:
>   'W8z0Ad5gLsIOYeGz3YnP1XQMapU=
>   sharedSecretBytes = StrConv("SharedSecretKeyStoredInConfig", _
>                               vbFromUnicode)
>
>   txtPlan = "16263392"
>   txtClaim = "3278053"
>   txtCSR = "DA3"
>   txtToken = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
>   txtDate = "5/5/2010 13:54"
>   stringToHash = txtPlan + txtClaim + txtCSR + txtToken + txtDate
>
>   HMACResult = Hash.HMAC_SHA1(stringToHash, sharedSecretBytes, False)
>   Debug.Print Hash.Base64Enc(HMACResult)
>
>   'Example 2 (with an empty String as the Key) ... result should be:
>   'MzFRObwYZoEvp1iQ/Xjx6GS2f9w=
>   sharedSecretBytes = StrConv("", vbFromUnicode)
>
>   txtPlan = "15847812"
>   txtClaim = "3270278"
>   txtCSR = "DA3"
>   txtToken = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
>   txtDate = "5/5/2010 13:54"
>   stringToHash = txtPlan + txtClaim + txtCSR + txtToken + txtDate
>
>   HMACResult = Hash.HMAC_SHA1(stringToHash, sharedSecretBytes, False)
>   Debug.Print Hash.Base64Enc(HMACResult)
>
>   'Example 3 (with the same Input as Example 2, but using the
>   'same Key as in Example 1 now) ... should deliver:
>   'hnf6YssSGCfkSyb546ONDI8xwZs=
>   sharedSecretBytes = StrConv("SharedSecretKeyStoredInConfig", _
>                               vbFromUnicode)
>
>   txtPlan = "15847812"
>   txtClaim = "3270278"
>   txtCSR = "DA3"
>   txtToken = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
>   txtDate = "5/5/2010 13:54"
>   stringToHash = txtPlan + txtClaim + txtCSR + txtToken + txtDate
>
>   HMACResult = Hash.HMAC_SHA1(stringToHash, sharedSecretBytes, False)
>   Debug.Print Hash.Base64Enc(HMACResult)
> End Sub
>
> Olaf- Hide quoted text -
>
> - Show quoted text -
Ah I see what I was doing wrong. I had inadvertently "hardcoded" the
key value rather than using the value in the text box.

Here is the code in my test form which now works correctly
Option Explicit

Private Hash As New cHash

Private Sub Form_Load()

'Example using no key value
txtKey.Text = ""
txtToken.Text = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
txtPlan.Text = "15847812"
txtClaim.Text = "3270278"
txtCSR.Text = "DA3"
txtDate.Text = "5/5/2010 13:54"
'Result of C# HMACSHA1 class = "MzFRObwYZoEvp1iQ/Xjx6GS2f9w="

' 'Example using test key value
' txtKey.Text = "SharedSecretKeyStoredInConfig"
' txtToken.Text = "56FCEFC9-579C-445E-9FD3-AFFD76C8619E"
' txtPlan.Text = "16263392"
' txtClaim.Text = "3278053"
' txtCSR.Text = "DA3"
' txtDate.Text = "5/5/2010 13:54"
' 'Result of C# HMACSHA1 class = "W8z0Ad5gLsIOYeGz3YnP1XQMapU="

End Sub

Private Sub cmdHash_Click()
Dim sharedSecretBytes() As Byte
Dim stringToHash As String
Dim HMACResult() As Byte

'OOPS!!! key value should not be hardcoded!!!
'sharedSecretBytes = StrConv("SharedSecretKeyStoredInConfig",
vbFromUnicode)
sharedSecretBytes = StrConv(txtKey.Text, vbFromUnicode)

stringToHash = txtPlan.Text + txtClaim.Text + txtCSR.Text +
txtToken.Text + txtDate.Text

HMACResult = Hash.HMAC_SHA1(stringToHash, sharedSecretBytes,
False)
txtHash = Hash.Base64Enc(HMACResult)

End Sub

It all works as it should now...thanks again for your help and
patience,
Steve