Last Update: 2024 - 01 - 25
Generating MD5, SHA-1, and SHA-512 Hashes in VBA Using the Windows API
by Philipp Stiefel, originally published 2023-07-14
last revision on 2024-02-17
The Windows API supports computing hash values using multiple different algorithms. Even though this feature is rarely used, it is extremely helpful when you need it.
First let’s talk about what a hash and a has function actually is.
Hashes and Hash Functions
A hash is a short(er) value that is generated by a one-way hash function from arbitrary input. There are several algorithms to compute hash values. Two very popular ones are the MD5 and the SHA-1 algorithm.
An MD5 hash will always be exactly 128 bits (16 bytes) long and is usually displayed as 32 hexadecimal characters. An SHA-1 hash will always be exactly 160 bits (20 bytes) long and is usually displayed as 40 hexadecimal characters. This always applies, regardless of the length of the input used to compute the hash.
Good hash functions have a very low chance of collisions. In other words: The probability that two different inputs result in the very same hash value should be extremely low.
A hash function is not encrypting data. It is a one-way computation that is (should!) not be reversible. Deducing the original data used to compute a hash should only be possible by using brute force.
Common use cases for hash functions are to compute the keys for a hash table or to verify passwords.
If you are implementing your own user/password authentication system for an Access database application and you store the passwords in clear text, anybody being able to see the raw data gets access to the passwords stored in the system. This is a huge flaw in a user/password system even by the fairly low security standards of Access applications.
The solution is not to store the password itself, but the hash computed from the password instead. With this approach anybody in possession of the password hashes is still unable to deduce the original passwords used. – At least in theory.
It is good practice to add a cryptographic salt to the input of the hash functions. A salt is some random information that is ideally unique to each hash computation. But then you also must store the salt to verify the passwords later. The salt causes the hash value computed by your application to be different from the hash value computed without the salt and thus makes it impossible to use a table of precomputed hash values and their inputs, a Rainbow Table, to deduce the passwords stored in your table.
Implementing MD5 and SHA-1 Hashes in VBA
It is possible to write an implementation of these hash algorithms in pure VBA. – I’ve seen multiple different MD5 implementations in VBA in the wild. – But luckily, we don’t have to.
Once again, the Windows API already has implementation of these hash algorithms we can used in VBA. More precisely: The Windows API gives us access to cryptography providers, which implement the hash algorithms.
I doesn’t make much sense to explain the control flow of the code here in detail as it is simple on the surface, but when we would like to look at a deeper level, I would have to reproduce the official Microsoft documentation, which you can read for yourself, if you want to dive that deep.
I was helping a user in the Access-O-Mania forum to convert existing Windows API code, originally written by forum user Nouba, to generate MD5 or SHA1 hashes to be compatible with the 64bit VBA environment.
As I was unable to locate a working 64bit implementation of these API functions anywhere on the internet. So, I publish my adaptation here as a downloadable VBA code module.
The code in this module can be used out-of-the-box to generate an MD5 hash or a SHA-1 hash from a String or Byte array by calling the GetHashOfString or GetHashOfByteArray function.
The module contains working 64bit declarations of the following Windows API functions from the Advapi32.DLL.
You can use this module as a basis to use or migrate these functions to the 64bit platform, even if your intended purpose is somewhat different from the functionality of this module.
MD5 and SHA-1 are no longer recommended to be used for cryptographic purposes. Still, in my opinion, these functions are still “good enough” for the security level we can achieve in a plain Access application. So, I provide the sample code with them being algorithms being supported out of the box.
Extending the Downloadable Module for Other Hash Algorithms
The Microsoft Base Cryptographic Provider v1.0 used in this example also supports a number of other hash algorithms, such as RC4 or RSA.
You can also employ this code to use different hash algorithms. Depending on the algorithm of your choice, you must load and use different cryptography providers by adding a new provider name and/or provider type.
To do this, you must look up the desired algorithm id (ALG_ID) and add it to the HashAlgorithmType enum. Then find then name of a suitable provider for the algorithm. Also required is the numeric provider type constant. The name of the constant is listed in the detail page for each provider from the provider list supplied with windows. You can then look up the numeric value of the provider type constant in the wincrypt.h file included in the Windows SDK
The GetProviderInfo function in the module illustrates how you can choose/configure the above options for computing the hash. – For more complex requirements, the values now hardcoded in the function should be replaced by a configuration table/file or be selected by user interaction.
For illustration and your convenience, I already added support for the SHA-512 hash algorithm by using the Microsoft Enhanced RSA and AES Cryptographic Provider.
Finally, here is the download link for the VBA module “modApiHash” which includes the above-mentioned functions for 32bit as well as 64bit VBA applications.
I will never share your email with anyone. You can unsubscribe any time.
© 1999 - 2024 by Philipp Stiefel - Privacy Policiy