0

I am new to programming and using Access 2010 VBA. I need to apply a set of rules to an xml file so that I can access an API. I have looked at different ways of doing it but have got stuck at each one due to my limited knowledge. If anyone could point me down the right path / offer some advice for doing this that would be great.

The rules:

  1. Canonify an xml file to the W3C C14N specification.
  2. SHA1 hash the xml into binary for further encoding
  3. Base64 and Base32 encode the SHA1 hash

My first problem is that I can not find any way to c14n the xml in VBA. So I skipped this step as I can make sure the xml is canonicalised up front. Though ideally this would be done as part of the encoding process in case someone changes the precedent xml.

I then started looking at the SHA1 hash and found this sample code:

http://vb.wikia.com/wiki/SHA-1.bas

The problem here is that the output hash is in hexadecimal which I think I need to convert into a byte array before converting to base64. I cant find any sample code to do this.

I then came across this post: Base64 HMAC SHA1 String in VBA

This is calling the .net cyptography library for HMACSHA1 but there is a library for SHA1:

http://msdn.microsoft.com/en-us/library/system.security.cryptography.sha1.aspx

The problem here is I have no idea how calling .net library's work. I need to run this software on 10 different windows machines in the office so I need to understand it.

Lastly I found the exact function I need written in vb.net:

http://blog.kuffs.co.uk/2009/07/calculating-irmark-for-hmrc-gateway.html

Again i've got no experience with .net and am unsure how to build this into a library that is accessible to access.

Community
  • 1
  • 1
user1607914
  • 105
  • 1
  • 3
  • 12

1 Answers1

2

Here you go:

Public Function SHA1Base64(ByVal sTextToHash As String)

    Dim asc As Object, enc As Object
    Dim TextToHash() As Byte
    Set asc = CreateObject("System.Text.UTF8Encoding")
    Set enc = CreateObject("System.Security.Cryptography.SHA1CryptoServiceProvider")
    TextToHash = asc.Getbytes_4(sTextToHash)
    Dim bytes() As Byte
    bytes = enc.ComputeHash_2((TextToHash))
    SHA1Base64 = EncodeBase64(bytes)
    Set asc = Nothing
    Set enc = Nothing

End Function

Private Function EncodeBase64(ByRef arrData() As Byte) As String

    Dim objXML As MSXML2.DOMDocument
    Dim objNode As MSXML2.IXMLDOMElement

    Set objXML = New MSXML2.DOMDocument

    ' byte array to base64
    Set objNode = objXML.createElement("b64")
    objNode.DataType = "bin.base64"
    objNode.nodeTypedValue = arrData
    EncodeBase64 = objNode.Text

    Set objNode = Nothing
    Set objXML = Nothing

End Function

Be aware that not nearly every .NET Framework library is available to be used in VBA (without wrapping them in COM callable wrapper dll's anyway). It just so happens that the functions you need can be called directly from VBA. And yes, it's true that there's really not much documentation on this that I'm aware of and it's anything but intuitive. GetBytes_4 and ComputerHash_2 are actually "overloaded" functions in .NET, something that doesn't exist in VBA. It's basically where you declare the same function multiple times, but each time it takes different quantity and/or different types of arguments.

You may want to compare the output of these functions to some known good output from somewhere else. I say that only because I know this code is returning something but I don't know if it's what you're looking for.

HK1
  • 11,941
  • 14
  • 64
  • 99