Convert Java Code To VBA Code (Encrypt To SHA512 SALTED)
I have searched for a way to encrypt the string to SHA512 With SALTED String
I found a code for JAVA but not for VBA. Can you help me converting this JAVA script to VBA?
package javaTests;
import java.security.*;
public class EncryptTest {
public static void main(String[] args) throws NoSuchAlgorithmException {
System.out.println(getSHA512("123", "AAZZ"));
}
public static String getSHA512(String toHash, String salt) {
for (int i = 0; i < 100000; i++) {
toHash = SHA512once(toHash + salt);
}
return SHA512once(toHash);
}
private static String SHA512once(String toHash) {
MessageDigest md;
String message = toHash;
try {
md = MessageDigest.getInstance("SHA-512");
md.update(message.getBytes());
byte[] mb = md.digest();
String out = "";
for (int i = 0; i < mb.length; i++) {
byte temp = mb[i];
@SuppressWarnings("deprecation")
String s = Integer.toHexString(new Byte(temp));
while (s.length() < 2) {
s = "0" + s;
}
s = s.substring(s.length() - 2);
out += s;
}
return (out);
} catch (NoSuchAlgorithmException e) {
System.out.println("Error: " + e.getMessage());
}
return "Error";
}
public static String salt(String toSalt, String salt) {
return "";
}
}
' Requires VB Editor Reference mscorlib.dll
Sub SHA512()
Dim toHash As String: toHash = "Hello World"
Dim salt As String: salt = "!"
Debug.Print GetSHA512Hash(toHash & salt)
End Sub
Function GetSHA512Hash(toHash As String) As String
' Ref: https://stackoverflow.com/questions/11394811/compute-sha512-on-vba-excel-2003
Dim text As Object: Set text = CreateObject("System.Text.UTF8Encoding")
Dim SHA512 As Object: Set SHA512 = CreateObject("System.Security.Cryptography.SHA512Managed")
GetSHA512Hash = ToBase64String(SHA512.ComputeHash_2((text.GetBytes_4(toHash))))
End Function
Function ToBase64String(rabyt)
' Ref: http://stackoverflow.com/questions/1118947/converting-binary-file-to-base64-string
With CreateObject("MSXML2.DOMDocument")
.LoadXML "<root />"
.DocumentElement.DataType = "bin.base64"
.DocumentElement.nodeTypedValue = rabyt
ToBase64String = Replace(.DocumentElement.text, vbLf, "")
End With
End Function
Having revisited this and looking into it in a bit more depth, the SHA-512 implementation is a bit more convoluted than I had previously realised. There is the repeated hashing of the salted result which I had missed and the functionality I coded used Base64 whereas the Java implementation is hexadecimal, so an incorrect string was continually being passed into the code, so no wonder it was out.
Updated code below which gives the same result as the Java code when trialled here
Sub SHA512()
Dim toHash As String: toHash = "123"
Dim Salt As String: Salt = "AAZZ"
Debug.Print toHash, GetSHA512Hash(toHash, Salt, 100000)
End Sub
Function GetSHA512Hash(ByVal toHash As String, Optional ByVal Salt As String, Optional Rounds As Long) As String
If Rounds = 0 Then Rounds = 100
If Rounds > 0 Then
Dim i As Long: For i = 1 To Rounds
toHash = SHA512Round(toHash + Salt)
Next i
End If
GetSHA512Hash = SHA512Round(toHash)
End Function
Function SHA512Round(toHash As String) As String
' Ref: https://stackoverflow.com/questions/11394811/compute-sha512-on-vba-excel-2003
Dim text As Object: Set text = CreateObject("System.Text.UTF8Encoding")
Dim SHA512 As Object: Set SHA512 = CreateObject("System.Security.Cryptography.SHA512Managed")
SHA512Round = EncodeHex(SHA512.ComputeHash_2(text.GetBytes_4(toHash)))
End Function
Function EncodeHex(ByVal strBytes) As String
Dim xmlNode16 As Object: Set xmlNode16 = CreateObject("MSXML2.DOMDocument").createElement("objNode")
xmlNode16.DataType = "bin.hex"
xmlNode16.nodeTypedValue = strBytes
EncodeHex = xmlNode16.text
Set xmlNode16 = Nothing
End Function
Setting
Rounds
as negative allows you to skip the salted string and gives the same kind of result as the GeeksforGeeks Site Test
I have also made the number of rounds optional as using 100,000 takes a bit more time in VBA than it does in Java.