473,624 Members | 1,957 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

SHA2 Cryptographic Hash Algorithm for VBA and VBScript

Rabbit
12,516 Recognized Expert Moderator MVP
INTRODUCTION
The Secure Hash Algorithm 2 is a series of cryptographic hash algorithms designed by the US National Security Agency (NSA) and published by the National Institute of Standards and Technology (NIST) as a government standard.

There is currently a competition being held by NIST to find a new family of algorithms for what will be named SHA-3. These new functions may not necessarily be derived from the SHA-2 algorithms.

One of the most widely used hash algorithms is the MD5 algorithm but substantial weaknesses have been found with it and it has been strongly recommended that MD5 be discontinued.

WHAT IS SHA2
SHA2 is a hash algorithm. A hash algorithm is basically a one-way encryption that outputs a fixed length. You can encrypt a text but you can not decrypt it. It is often used for password storage and message authentication.

Instead of storing a plaintext password, what you do is precalculate the hash of the password. When they enter in the password, you hash their input and compare it to the hash that you have stored. This way, even if they know what the result of the hash is, they do not know the original password that created the hash. It would be infeasible for them to calculate a password that would result in the same hash.

On a side note, this is how Linux based utilities reset Windows passwords. They overwrite the hash value that is stored with the user account. If security is an issue, what you should do is encrypt all the files of that user using the password. That way, even if they overwrite the hash and log in as that user, they can not view the files because they don't have the password to decrypt the data.

Hashes are often used in internet communication to authenticate messages. The sender will hash the original data and send it along with the encrypted data. The receiver will then decrypt the data and recalculate the hash from the unencrypted data. If the hashes match, then he is assured that the data was received as intended. If you were to send just the encrypted data, someone could conceivably intercept the message, flip a bit in the message, and pass it along. The receiver would never know the message was changed.

GENERAL WEAKNESSES OF HASH ALGORITHMS
Because a hash algorithm is intended to return a fixed length regardless of the size of the input, there will invariably be collisions. Collisions are when two different texts produce the same hash. The longer the hash, the less likely the chance of a collision.

When using hashes to store passwords, it does not prevent brute force cracking of a password. Also, since the same text hashed using an algorithm always produces the same hash, it is strongly recommended that a nonce is used to defeat rainbow table attacks. A nonce, initialization vector, or salt are basically random bits that are used with the key so that even though you are using the same key, each message is different because the random bits in effect change the key that is used. A rainbow table is a precomputed table of hashes of popular passwords. All the hacker would have to do is compare the precomputed hashes with the stored hashes to see if there's a match. A nonce defeats this by changing the actual text that is being hashed.

HOW SHA2 WORKS
SHA2 breaks messages into 64 byte chunks, does mathematical transformations on each chunk, and adds them to a hash value. It does this for every chunk and adds them to the same value. In the end, you get a fixed length output.

SPECIFIC WEAKNESSES OF SHA2
There are currently no known successful attacks that will break all rounds of the SHA2 256-bit algorithm.

SAMPLE IMPLEMENTATION
This is an implementation of the SHA2 256-bit algorithm. It even works in a Visual Basic Script and was, in fact, coded specifically for VBScript. But it should be directly portable to VBA. It takes a string, hashes it, and returns the result as a 32 item array containing the hashed value. I validated the output against official SHA2 hashes.

For this to work, it has to use 32-bit unsigned integers but seeing as how that is not available as a datatype in VBA, we have to use doubles instead. However, the MOD, XOR, AND, and NOT operators will overflow when using doubles. In addition to that, there is no bit shift operators or functions in VBA. So I had to create those.

Expand|Select|Wrap|Line Numbers
  1. Function SHA(ByVal sMessage)
  2.     Dim i, result(32), temp(8) As Double, fraccubeprimes, hashValues
  3.     Dim done512, index512, words(64) As Double, index32, mask(4)
  4.     Dim s0, s1, t1, t2, maj, ch, strLen
  5.  
  6.     mask(0) = 4294967296#
  7.     mask(1) = 16777216
  8.     mask(2) = 65536
  9.     mask(3) = 256
  10.  
  11.     hashValues = Array( _
  12.         1779033703, 3144134277#, 1013904242, 2773480762#, _
  13.         1359893119, 2600822924#, 528734635, 1541459225)
  14.  
  15.     fraccubeprimes = Array( _
  16.         1116352408, 1899447441, 3049323471#, 3921009573#, 961987163, 1508970993, 2453635748#, 2870763221#, _
  17.         3624381080#, 310598401, 607225278, 1426881987, 1925078388, 2162078206#, 2614888103#, 3248222580#, _
  18.         3835390401#, 4022224774#, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, _
  19.         2554220882#, 2821834349#, 2952996808#, 3210313671#, 3336571891#, 3584528711#, 113926993, 338241895, _
  20.         666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350#, 2456956037#, _
  21.         2730485921#, 2820302411#, 3259730800#, 3345764771#, 3516065817#, 3600352804#, 4094571909#, 275423344, _
  22.         430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, _
  23.         1955562222, 2024104815, 2227730452#, 2361852424#, 2428436474#, 2756734187#, 3204031479#, 3329325298#)
  24.  
  25.     sMessage = Nz(sMessage, "")
  26.     strLen = Len(sMessage) * 8
  27.     sMessage = sMessage & Chr(128)
  28.     done512 = False
  29.     index512 = 0
  30.  
  31.     If (Len(sMessage) Mod 64) < 56 Then
  32.         sMessage = sMessage & String(56 - (Len(sMessage) Mod 64), Chr(0))
  33.     ElseIf (Len(sMessage) Mod 64) > 56 Then
  34.         sMessage = sMessage & String(120 - (Len(sMessage) Mod 64), Chr(0))
  35.     End If
  36.     sMessage = sMessage & Chr(0) & Chr(0) & Chr(0) & Chr(0)
  37.  
  38.     sMessage = sMessage & Chr(Int((strLen / mask(0) - Int(strLen / mask(0))) * 256))
  39.     sMessage = sMessage & Chr(Int((strLen / mask(1) - Int(strLen / mask(1))) * 256))
  40.     sMessage = sMessage & Chr(Int((strLen / mask(2) - Int(strLen / mask(2))) * 256))
  41.     sMessage = sMessage & Chr(Int((strLen / mask(3) - Int(strLen / mask(3))) * 256))
  42.  
  43.     Do Until done512
  44.         For i = 0 To 15
  45.             words(i) = Asc(Mid(sMessage, index512 * 64 + i * 4 + 1, 1)) * mask(1) + Asc(Mid(sMessage, index512 * 64 + i * 4 + 2, 1)) * mask(2) + Asc(Mid(sMessage, index512 * 64 + i * 4 + 3, 1)) * mask(3) + Asc(Mid(sMessage, index512 * 64 + i * 4 + 4, 1))
  46.         Next
  47.  
  48.         For i = 16 To 63
  49.             s0 = largeXor(largeXor(rightRotate(words(i - 15), 7, 32), rightRotate(words(i - 15), 18, 32), 32), Int(words(i - 15) / 8), 32)
  50.             s1 = largeXor(largeXor(rightRotate(words(i - 2), 17, 32), rightRotate(words(i - 2), 19, 32), 32), Int(words(i - 2) / 1024), 32)
  51.             words(i) = Mod32Bit(words(i - 16) + s0 + words(i - 7) + s1)
  52.         Next
  53.  
  54.         For i = 0 To 7
  55.             temp(i) = hashValues(i)
  56.         Next
  57.  
  58.         For i = 0 To 63
  59.             s0 = largeXor(largeXor(rightRotate(temp(0), 2, 32), rightRotate(temp(0), 13, 32), 32), rightRotate(temp(0), 22, 32), 32)
  60.             maj = largeXor(largeXor(largeAnd(temp(0), temp(1), 32), largeAnd(temp(0), temp(2), 32), 32), largeAnd(temp(1), temp(2), 32), 32)
  61.             t2 = Mod32Bit(s0 + maj)
  62.             s1 = largeXor(largeXor(rightRotate(temp(4), 6, 32), rightRotate(temp(4), 11, 32), 32), rightRotate(temp(4), 25, 32), 32)
  63.             ch = largeXor(largeAnd(temp(4), temp(5), 32), largeAnd(largeNot(temp(4), 32), temp(6), 32), 32)
  64.             t1 = Mod32Bit(temp(7) + s1 + ch + fraccubeprimes(i) + words(i))
  65.  
  66.             temp(7) = temp(6)
  67.             temp(6) = temp(5)
  68.             temp(5) = temp(4)
  69.             temp(4) = Mod32Bit(temp(3) + t1)
  70.             temp(3) = temp(2)
  71.             temp(2) = temp(1)
  72.             temp(1) = temp(0)
  73.             temp(0) = Mod32Bit(t1 + t2)
  74.         Next
  75.  
  76.         For i = 0 To 7
  77.             hashValues(i) = Mod32Bit(hashValues(i) + temp(i))
  78.         Next
  79.  
  80.         If (index512 + 1) * 64 >= Len(sMessage) Then done512 = True
  81.         index512 = index512 + 1
  82.     Loop
  83.  
  84.     For i = 0 To 31
  85.         result(i) = Int((hashValues(i \ 4) / mask(i Mod 4) - Int(hashValues(i \ 4) / mask(i Mod 4))) * 256)
  86.     Next
  87.  
  88.     SHA = result
  89. End Function
  90.  
  91. Function Mod32Bit(value)
  92.     Mod32Bit = Int((value / 4294967296# - Int(value / 4294967296#)) * 4294967296#)
  93. End Function
  94.  
  95. Function rightRotate(value, amount, totalBits)
  96.     'To leftRotate, make amount = totalBits - amount
  97.     Dim i
  98.     rightRotate = 0
  99.  
  100.     For i = 0 To (totalBits - 1)
  101.         If i >= amount Then
  102.             rightRotate = rightRotate + (Int((value / (2 ^ (i + 1)) - Int(value / (2 ^ (i + 1)))) * 2)) * 2 ^ (i - amount)
  103.         Else
  104.             rightRotate = rightRotate + (Int((value / (2 ^ (i + 1)) - Int(value / (2 ^ (i + 1)))) * 2)) * 2 ^ (totalBits - amount + i)
  105.         End If
  106.     Next
  107. End Function
  108.  
  109. Function largeXor(value, xorValue, totalBits)
  110.     Dim i, a, b
  111.     largeXor = 0
  112.  
  113.     For i = 0 To (totalBits - 1)
  114.         a = (Int((value / (2 ^ (i + 1)) - Int(value / (2 ^ (i + 1)))) * 2))
  115.         b = (Int((xorValue / (2 ^ (i + 1)) - Int(xorValue / (2 ^ (i + 1)))) * 2))
  116.         If a <> b Then
  117.             largeXor = largeXor + 2 ^ i
  118.         End If
  119.     Next
  120. End Function
  121.  
  122. Function largeNot(value, totalBits)
  123.     Dim i, a
  124.     largeNot = 0
  125.  
  126.     For i = 0 To (totalBits - 1)
  127.         a = Int((value / (2 ^ (i + 1)) - Int(value / (2 ^ (i + 1)))) * 2)
  128.         If a = 0 Then
  129.             largeNot = largeNot + 2 ^ i
  130.         End If
  131.     Next
  132. End Function
  133.  
  134. Function largeAnd(value, andValue, totalBits)
  135.     Dim i, a, b
  136.     largeAnd = 0
  137.  
  138.     For i = 0 To (totalBits - 1)
  139.         a = Int((value / (2 ^ (i + 1)) - Int(value / (2 ^ (i + 1)))) * 2)
  140.         b = (Int((andValue / (2 ^ (i + 1)) - Int(andValue / (2 ^ (i + 1)))) * 2))
  141.         If a = 1 And b = 1 Then
  142.             largeAnd = largeAnd + 2 ^ i
  143.         End If
  144.     Next
  145. End Function
Jan 25 '11 #1
24 44524
paerison
1 New Member
SHA2 Cryptographic Hash Algorithm for VBA and VBScript
Here's a bit that will save some CPU cycles and such
Expand|Select|Wrap|Line Numbers
  1. 31:     If (Len(sMessage) Mod 60) <> 0 Then 
  2. 32:        For i = (Len(sMessage) Mod 60) To 59 
  3. 33:            sMessage = sMessage & Chr(0) 
  4. 34:     Next 
  5. 35:    End If 
  6.  
replace with
Expand|Select|Wrap|Line Numbers
  1. 31: sMessage = sMessage & String(60 - Len(sMessage) Mod 60, Chr(0))
  2.  
confirmed VBA 14 (Office 2010)
Sep 12 '12 #2
NeoPa
32,567 Recognized Expert Moderator MVP
Indeed. Good suggestion.
Sep 12 '12 #3
gaultz
1 New Member
Hmmm...not sure what I am missing, but I get the same hash result for the following:
SHA(string(64," X"))
SHA(string(65," X"))
SHA(string(66," X"))
and so on
Oct 10 '12 #4
Rabbit
12,516 Recognized Expert Moderator MVP
I will fix the code for messages longer than 64 characters and repost.
YEA!
I was just trying to figure that out once I confirmed Gaultz's discovery
-z
Oct 10 '12 #5
Rabbit
12,516 Recognized Expert Moderator MVP
The code has been fixed. I also noticed a bug for messages between 61 and 64 characters that has also been fixed. Thanks for pointing this out for me.

I can make no guarantee on my fix though as I have no test values to use that are 61+ characters long.
Oct 11 '12 #6
zmbd
5,501 Recognized Expert Moderator Expert
I caught the changes on lines 31 thru 35; however, I don't see any other changes.
When I put these into the VBA version, the same issue with truncation past 64 is occuring.
Oct 11 '12 #7
Rabbit
12,516 Recognized Expert Moderator MVP
I'm seeing different results, can you post your input and output?
Oct 11 '12 #8
Rabbit
12,516 Recognized Expert Moderator MVP
@z, that wasn't the only change. There's a small and vital change on line 44 that's the crux of the matter.
Oct 11 '12 #9
Rabbit
12,516 Recognized Expert Moderator MVP
Lines 31-34 was to fix the issue for lengths greater than 60. Line 44 is the fix for lengths greater than 64.
Oct 11 '12 #10

Sign in to post your reply or Sign up for a free account.

Similar topics

7
2739
by: Benoît Dejean | last post by:
hi. Is the hash() algorithm standard ? Does hash(some_string) will always return the same hash code on every arch ? i need to use a ~checksum function, like md5, but i was also thinking about hash() which is obviously simpler. So i can safely rely on hash() behaviour so i can use it to generate ~strong and portable identifier/checksum ? thank you
1
3272
by: Pieter Claassen | last post by:
Is there any reasonable standard hash table storage in C on Linux? AFAICT the one in glibc has a data struct where the key and value pairs both have to be null terminated pointers. In my case, that is fine for the key, but I need to store a complex struct as the value and short of doing dangerous things like printing the memory location of the value struct and then recasting it when I want to get to the struct (which I think is...
0
1821
by: Nuri YILMAZ | last post by:
Dear Member, Today, the hot.Net members received both C# and VB.NET code with subject "158# SHA1 (Secure Hash Algorithm) class for the passwords and the others". If you didn't receive it, this means you are not a hot.Net member. "HotDotNet" is a Yahoo group which sends to its members both C# and VB.NET code (fully tested). Please click the link below to join.
1
2872
by: Fernando Barsoba | last post by:
Hi all, First of all, I'd like to thank you "Skarmander" and "Flash Gordon" for the help they provided me: Skarmander's algorithm and Flash's modifications helped me a lot. Here's the problem I had and the question which I still have regarding that problem: I tried to send a hex string to a function that performed message
12
4517
by: wjb131 | last post by:
hi all, below you find my simple python version of MD2 algorithm as described in RFC1319 (http://rfc1319.x42.com/MD2). It produces correct results for strings shorter than 16 Bytes and wrong results for longer strings. I can't find what's wrong. Can anybody help?
6
3402
by: thecodemachine | last post by:
Hi, I'm looking for a fast and simple one to one hash function, suitable for longer strings (up to 2048 in length). I'd like keys to be relatively short, I doubt I'd be creating more than 256 keys.. I could use md5 but even that is more than I need, and I assume not the fastest algorithm (?), so I'm reluctant to use it. I've been looking around a lot, not finding much anything come to mind?
4
3151
by: Bo Peng | last post by:
Dear list, I am looking for a way to store a large amount of unique sequences that will be accessed by objects. The most important operations are: 1. Direct access to the sequences (from pointers stored in each object). Access through key lookup is not acceptable. 2. Given a new sequence, determine if it is already in the factory of sequences. If so, increase the reference count of the existing sequence
9
6423
by: DotNetNewbie | last post by:
Hello, I need a simple hash algorithm that will detect duplicate content in my application. I want to hash not just the content, but a few other parameters also like EmployeeID and DepartmentID. So something like:
4
3458
by: macm | last post by:
Hi Folks I tested <?php echo 'sha256=>' .hash('sha256', 'The quick brown fox jumped over the lazy dog.') .'</br>'; echo 'sha384=>' .hash('sha384', 'The quick brown fox jumped over the lazy dog.') .'</br>'; echo 'sha512=>' .hash('sha512', 'The quick brown fox jumped over the
0
8238
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
8174
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
8336
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
7164
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6111
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
4082
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4176
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2607
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1786
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.