How to generate MD5 using VBScript in classic ASP?
Asked Answered
U

6

15

I need to generate an MD5 in my application.

I've tried google but only find PHP code for MD5. I need to connect to a client system that validates using MD5 hash but their code is in PHP, mine is in Classic ASP using VBScript.

My server is .Net supported so I cannot use the PHP script. Is there any such MD5 code for VBScript in Classic ASP?

Umbles answered 17/4, 2012 at 20:32 Comment(4)
Also: fyi, but Windows IIS will run php code just fine. Simply create a different application pool with a handler for the FastCGI module.Sean
possible duplicate of md5/hash on vb6?Rhinarium
No no not vb 6 but vb script in asp pages?Umbles
@Joel Coehoorn my MD5 is for the one page. Are you saying I can create that page in php and then put that page in a different application pool?Umbles
T
4

I have no idea if this code even works, since I have no way of testing it. However, it seems to be what you are asking for.

http://www.bullzip.com/md5/vb/md5-vb-class.htm

Here is an interesting article by Jeff Attwood on hashes. He has some important things to say about MD5:

http://www.codinghorror.com/blog/2012/04/speed-hashing.html

Tonicity answered 17/4, 2012 at 20:45 Comment(2)
Thanks for the reading @Tonicity but I don't really have much of a choice, the system I am connecting to heavily uses MD5 hash keys for autehtication and these are the requirements they have given inorder to connect to them. I will try out the bullzip code and adviseUmbles
This is not even vbscript the implementation is for vb.Dragone
C
44

Update 2017-02-21 - Now with added HMACSHA256 for JWTs

Update 2016-07-05 - Now with added SHA1 and SHA256

Right, for all of you who have been struggling with this (like myself) and want to know, it is possible!

The following code is split up into several functions so that you can either MD5/sha1/sha256 a string, or a file.

I borrowed the functions GetBytes and BytesToBase64 from another stackexchange, and the code within stringToUTFBytes is based on another stackexchange.

function md5hashBytes(aBytes)
    Dim MD5
    set MD5 = CreateObject("System.Security.Cryptography.MD5CryptoServiceProvider")

    MD5.Initialize()
    'Note you MUST use computehash_2 to get the correct version of this method, and the bytes MUST be double wrapped in brackets to ensure they get passed in correctly.
    md5hashBytes = MD5.ComputeHash_2( (aBytes) )
end function

function sha1hashBytes(aBytes)
    Dim sha1
    set sha1 = CreateObject("System.Security.Cryptography.SHA1Managed")

    sha1.Initialize()
    'Note you MUST use computehash_2 to get the correct version of this method, and the bytes MUST be double wrapped in brackets to ensure they get passed in correctly.
    sha1hashBytes = sha1.ComputeHash_2( (aBytes) )
end function

function sha256hashBytes(aBytes)
    Dim sha256
    set sha256 = CreateObject("System.Security.Cryptography.SHA256Managed")

    sha256.Initialize()
    'Note you MUST use computehash_2 to get the correct version of this method, and the bytes MUST be double wrapped in brackets to ensure they get passed in correctly.
    sha256hashBytes = sha256.ComputeHash_2( (aBytes) )
end function

function sha256HMACBytes(aBytes, aKey)
    Dim sha256
    set sha256 = CreateObject("System.Security.Cryptography.HMACSHA256")

    sha256.Initialize()
    sha256.key=aKey
    'Note you MUST use computehash_2 to get the correct version of this method, and the bytes MUST be double wrapped in brackets to ensure they get passed in correctly.
    sha256HMACBytes = sha256.ComputeHash_2( (aBytes) )
end function

function stringToUTFBytes(aString)
    Dim UTF8
    Set UTF8 = CreateObject("System.Text.UTF8Encoding")
    stringToUTFBytes = UTF8.GetBytes_4(aString)
end function

function bytesToHex(aBytes)
    dim hexStr, x
    for x=1 to lenb(aBytes)
        hexStr= hex(ascb(midb( (aBytes),x,1)))
        if len(hexStr)=1 then hexStr="0" & hexStr
        bytesToHex=bytesToHex & hexStr
    next
end function

Function BytesToBase64(varBytes)
    With CreateObject("MSXML2.DomDocument").CreateElement("b64")
        .dataType = "bin.base64"
        .nodeTypedValue = varBytes
        BytesToBase64 = .Text
    End With
End Function

'Special version that produces the URLEncoded variant of Base64 used in JWTs.
Function BytesToBase64UrlEncode(varBytes)
    With CreateObject("MSXML2.DomDocument").CreateElement("b64")
        .dataType = "bin.base64"
        .nodeTypedValue = varBytes
        BytesToBase64UrlEncode = replace(replace(replace(replace(replace(.Text,chr(13),""),chr(10),""),"+", "-"),"/", "_"),"=", "")
    End With
End Function

Function GetBytes(sPath)
    With CreateObject("Adodb.Stream")
        .Type = 1 ' adTypeBinary
        .Open
        .LoadFromFile sPath
        .Position = 0
        GetBytes = .Read
        .Close
    End With
End Function

These can be used as follows:

BytesToBase64(md5hashBytes(stringToUTFBytes("Hello World")))

Produces: sQqNsWTgdUEFt6mb5y4/5Q==

bytesToHex(md5hashBytes(stringToUTFBytes("Hello World")))

Produces: B10A8DB164E0754105B7A99BE72E3FE5

For SHA1:

bytesToHex(sha1hashBytes(stringToUTFBytes("Hello World")))

Produces: 0A4D55A8D778E5022FAB701977C5D840BBC486D0

For SHA256:

bytesToHex(sha256hashBytes(stringToUTFBytes("Hello World")))

Produces: A591A6D40BF420404A011733CFB7B190D62C65BF0BCDA32B57B277D9AD9F146E

To get the MD5 of a file (useful for Amazon S3 MD5 checking):

BytesToBase64(md5hashBytes(GetBytes(sPath)))

Where sPath is the path to the local file.

And finally, to create a JWT:

'define the JWT header, needs to be converted to UTF bytes:
aHead=stringToUTFBytes("{""alg"":""HS256"",""typ"":""JWT""}")

'define the JWT payload, again needs to be converted to UTF Bytes.
aPayload=stringToUTFBytes("{""sub"":""1234567890"",""name"":""John Doe"",""admin"":true}") 

'Your shared key.
theKey="mySuperSecret"

aSigSource=stringToUTFBytes(BytesToBase64UrlEncode(aHead) & "." & BytesToBase64UrlEncode(aPayload))

'The full JWT correctly Base 64 URL encoded.
aJWT=BytesToBase64UrlEncode(aHead) & "." & BytesToBase64UrlEncode(aPayload) & "." & BytesToBase64UrlEncode(sha256HMACBytes(aSigSource,stringToUTFBytes(theKey)))

Which will produce the following valid JWT: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.7ofvtkn0z_pTl6WcqRTxw-4eSE3NqcEq9_3ax0YcuIQ

Cesaro answered 16/7, 2015 at 12:4 Comment(3)
Best Answer so far... Exactly what I was looking for except I used bytesToHex(md5hashBytes(GetBytes(sPath))) to get the value I needed from the files. Excellent compilation of other work sir and best part is that there is no miscellaneous executable or libraries required. The MD5 aligns right up with sigcheck and other misc executable utilities.Chalybite
This is mint. I'd been struggling with this one for a while. Nicely put together.Attis
Very nice! Exactly what I wanted to find.I just added this line WScript.Echo bytesToHex(sha256hashBytes(GetBytes("the path to my file")))Abacist
L
7

Here is a readable and downloadable version of MD5 as VBS script:

https://github.com/Wikinaut/md5.vbs

It's the code from http://chayoung.tistory.com/entry/VBScript-MD5 (thank you for this unique piece of code).

Lucillalucille answered 21/2, 2013 at 14:52 Comment(1)
Works without issue, Brilliant!Flasher
U
6

Thanks for all the links provided above, they were useful but this one I found really did the job if anybody ever needs it. VBScript-MD5

Umbles answered 18/4, 2012 at 4:37 Comment(0)
T
4

I have no idea if this code even works, since I have no way of testing it. However, it seems to be what you are asking for.

http://www.bullzip.com/md5/vb/md5-vb-class.htm

Here is an interesting article by Jeff Attwood on hashes. He has some important things to say about MD5:

http://www.codinghorror.com/blog/2012/04/speed-hashing.html

Tonicity answered 17/4, 2012 at 20:45 Comment(2)
Thanks for the reading @Tonicity but I don't really have much of a choice, the system I am connecting to heavily uses MD5 hash keys for autehtication and these are the requirements they have given inorder to connect to them. I will try out the bullzip code and adviseUmbles
This is not even vbscript the implementation is for vb.Dragone
N
3

First of all, thank you SgtWilko! :)

Based on your collected information, I've done one function for all (not for base64/Files).
Your code was very useful for me, but I was searching for a more PHP alike (simple) Function to deal with plain text and with a more explicit code.

Edited:
Based on the issue How to hash a UTF-8 string in Classic ASP, I come up with the ADODB.Stream solution. You can now use non-English characters.

Edited:
Parameter PlainText was changed to Target. You can now use the HMAC versions.
Just use the Target parameter as an array.

Target(0) = PlainText
Target(1) = SharedKey

Thank you again SgtWilko ;)

Announcing the first SHA1 collision (Google Security Blog) February 23, 2017.

With this function you can hash the plain text into:
MD5, RIPEMD160, SHA1, SHA256, SHA384, SHA512, HMACMD5, HMACRIPEMD160, HMACSHA1, HMACSHA256, HMACSHA384 and HMACSHA512
If you need more you can find it in: System.Security.Cryptography Namespace

Function Hash(HashType, Target)
    On Error Resume Next

    Dim PlainText

    If IsArray(Target) = True Then PlainText = Target(0) Else PlainText = Target End If

    With CreateObject("ADODB.Stream")
        .Open
        .CharSet = "Windows-1252"
        .WriteText PlainText
        .Position = 0
        .CharSet = "UTF-8"
        PlainText = .ReadText
        .Close
    End With

    Set UTF8Encoding = CreateObject("System.Text.UTF8Encoding")
    Dim PlainTextToBytes, BytesToHashedBytes, HashedBytesToHex

    PlainTextToBytes = UTF8Encoding.GetBytes_4(PlainText)

    Select Case HashType
        Case "md5": Set Cryptography = CreateObject("System.Security.Cryptography.MD5CryptoServiceProvider") '< 64 (collisions found)
        Case "ripemd160": Set Cryptography = CreateObject("System.Security.Cryptography.RIPEMD160Managed")
        Case "sha1": Set Cryptography = CreateObject("System.Security.Cryptography.SHA1Managed") '< 80 (collision found)
        Case "sha256": Set Cryptography = CreateObject("System.Security.Cryptography.SHA256Managed")
        Case "sha384": Set Cryptography = CreateObject("System.Security.Cryptography.SHA384Managed")
        Case "sha512": Set Cryptography = CreateObject("System.Security.Cryptography.SHA512Managed")
        Case "md5HMAC": Set Cryptography = CreateObject("System.Security.Cryptography.HMACMD5")
        Case "ripemd160HMAC": Set Cryptography = CreateObject("System.Security.Cryptography.HMACRIPEMD160")
        Case "sha1HMAC": Set Cryptography = CreateObject("System.Security.Cryptography.HMACSHA1")
        Case "sha256HMAC": Set Cryptography = CreateObject("System.Security.Cryptography.HMACSHA256")
        Case "sha384HMAC": Set Cryptography = CreateObject("System.Security.Cryptography.HMACSHA384")
        Case "sha512HMAC": Set Cryptography = CreateObject("System.Security.Cryptography.HMACSHA512")
    End Select

    Cryptography.Initialize()

    If IsArray(Target) = True Then Cryptography.Key = UTF8Encoding.GetBytes_4(Target(1))

    BytesToHashedBytes = Cryptography.ComputeHash_2((PlainTextToBytes))

    For x = 1 To LenB(BytesToHashedBytes)
        HashedBytesToHex = HashedBytesToHex & Right("0" & Hex(AscB(MidB(BytesToHashedBytes, x, 1))), 2)
    Next

    If Err.Number <> 0 Then Response.Write(Err.Description) Else Hash = LCase(HashedBytesToHex)

    On Error GoTo 0
End Function

These can be used as follows:

Hash("sha512", "Hello World")

Produces:
2c74fd17edafd80e8447b0d46741ee243b7eb74dd2149a0ab1b9246fb30382f27e853d8585719e0e67cbda0daa8f51671064615d645ae27acb15bfb1447f459b

Hash("sha256", "Hello World")

Produces:
a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e

Hash("md5", "muñeca")

Produces:
ea07bec1f37f4b56ebe368355d1c058f

Hash("sha512HMAC", Array("Hello World", "Shared Key"))

Produces:
28e72824c48da5a5f14b59246905d2839e7c50e271fc078b1c0a75c89b6a3998746bd8b2dc1764b19d312702cf5e15b38ce799156af28b98ce08b85e4df65b32

Nisse answered 15/2, 2017 at 17:31 Comment(2)
Glad I could help. You may be able to get around the UTF-8 issue by setting the codepage & charset in your ASP file: Response.CodePage=65001 Response.Charset="UTF-8" and if you also set it in the session asp will also interpret the responses correctly: Session.Codepage=65001Cesaro
This does depend on having the correct encoding setup in the ASP page as @Cesaro suggested, the whole conversion ADODB.Stream is pointless step and likely to cause inconsistent results.Dragone
H
1

There is Javascript code that produces an MD5 checksum. One of them, derived from the Google closure library, is available here.

It's pretty easy to produce a Windows Script Component from the Javascript, then call that component from any COM-enabled language, including VB.

Here's a working example.

Homeostasis answered 17/4, 2012 at 20:45 Comment(1)
These links seem to be dead, fyiConvexity

© 2022 - 2024 — McMap. All rights reserved.