Hello, I am Ryan Marcus, from the x86 forums.
Joe has told me that you ported some of iago's code for hashing
usernames/passwords and cdkeys to VB... Would you mind sending those to
me?
Thanks in advance for helping out the newby!
--
Thanks, Ryan Marcus
It wasn't iago's code. I used documentation on the official SHA-1 implimentation as well as the code from Blizzard's battle.snp to form my own.
Note that usernames are not hashed, only passwords and these functions can also be used to hash CD-Keys. You may also want to know that X-SHA-1 is only used for hashing on legacy products.
' Copyright (C) 2005 Eric Evans (RVictim87@GMail.com)
Option Explicit
Private m_hashbuf(20) As Long
' XSHA1Init()
Private Sub Class_Initialize()
m_hashbuf(0) = &H67452301 ' A
m_hashbuf(1) = &HEFCDAB89 ' B
m_hashbuf(2) = &H98BADCFE ' C
m_hashbuf(3) = &H10325476 ' D
m_hashbuf(4) = &HC3D2E1F0 ' E
End Sub
Public Function XSHA1Hash(ByVal tmpBuf As String) As String
Dim intBufLen As Integer
Dim intPos As Integer
Dim intSubLen As Integer
Dim strBuf As String
intBufLen = Len(tmpBuf)
' Note: Blizzard clients only support a single 512-bit (64 Bytes) message block
For intPos = 1 To intBufLen Step 64
intSubLen = (intBufLen - (intPos - 1))
' Message padding
If (intSubLen > 64) Then: intSubLen = 64
strBuf = Mid$(tmpBuf, intPos, intSubLen) & String$(64 - intSubLen, Chr$(0))
Call CopyMemory(m_hashbuf(5), ByVal strBuf, 64)
Call XSHA1ProcessMessageBlock(m_hashbuf)
Next intPos
XSHA1Hash = String$(20, Chr$(0))
Call CopyMemory(ByVal XSHA1Hash, m_hashbuf(0), 20)
End Function
' Hash 512-bit (64 Bytes) message block
Private Sub XSHA1ProcessMessageBlock(ByRef lngHashBuf() As Long)
Dim k(4) As Long
Dim W(80) As Long
Dim A As Long
Dim b As Long
Dim C As Long
Dim D As Long
Dim E As Long
Dim Temp As Long
Dim t As Long
Dim p As Long
Dim i As Integer
' Initialize constants
k(0) = &H5A827999
k(1) = &H6ED9EBA1
k(2) = &H8F1BBCDC
k(3) = &HCA62C1D6
For t = 0 To 15
W(t) = lngHashBuf(t + 5)
Next
For t = 16 To 79
Temp = W(t - 16) Xor W(t - 14) Xor W(t - 8) Xor W(t - 3)
W(t) = modGlobals.RoL(1, Temp)
' Standard SHA-1:
' W(t) = modGlobals.RoL(temp, 1)
Next
A = lngHashBuf(0)
b = lngHashBuf(1)
C = lngHashBuf(2)
D = lngHashBuf(3)
E = lngHashBuf(4)
t = 0
' Round one:
For i = 0 To 19
Temp = W(t)
Temp = modGlobals.UnsignedAdd(Temp, E)
Temp = modGlobals.UnsignedAdd(Temp, modGlobals.RoL(A, 5))
Temp = modGlobals.UnsignedAdd(Temp, ((b And C) Or ((Not b) And D)))
Temp = modGlobals.UnsignedAdd(Temp, k(0))
E = D
D = C
C = modGlobals.RoL(b, 30)
b = A
A = Temp
t = t + 1
Next i
' Round two:
For i = 0 To 19
Temp = W(t)
Temp = modGlobals.UnsignedAdd(Temp, E)
Temp = modGlobals.UnsignedAdd(Temp, modGlobals.RoL(A, 5))
Temp = modGlobals.UnsignedAdd(Temp, (b Xor C Xor D))
Temp = modGlobals.UnsignedAdd(Temp, k(1))
E = D
D = C
C = modGlobals.RoL(b, 30)
b = A
A = Temp
t = t + 1
Next i
' Round three:
For i = 0 To 19
Temp = W(t)
Temp = modGlobals.UnsignedAdd(Temp, E)
Temp = modGlobals.UnsignedAdd(Temp, modGlobals.RoL(A, 5))
Temp = modGlobals.UnsignedAdd(Temp, (b And C) Or (b And D) Or (C And D))
Temp = modGlobals.UnsignedAdd(Temp, k(2))
E = D
D = C
C = modGlobals.RoL(b, 30)
b = A
A = Temp
t = t + 1
Next i
' Round four:
For i = 0 To 19
Temp = W(t)
Temp = modGlobals.UnsignedAdd(Temp, E)
Temp = modGlobals.UnsignedAdd(Temp, modGlobals.RoL(A, 5))
Temp = modGlobals.UnsignedAdd(Temp, (b Xor C Xor D))
Temp = modGlobals.UnsignedAdd(Temp, k(3))
E = D
D = C
C = modGlobals.RoL(b, 30)
b = A
A = Temp
t = t + 1
Next i
lngHashBuf(0) = modGlobals.UnsignedAdd(lngHashBuf(0), A)
lngHashBuf(1) = modGlobals.UnsignedAdd(lngHashBuf(1), b)
lngHashBuf(2) = modGlobals.UnsignedAdd(lngHashBuf(2), C)
lngHashBuf(3) = modGlobals.UnsignedAdd(lngHashBuf(3), D)
lngHashBuf(4) = modGlobals.UnsignedAdd(lngHashBuf(4), E)
End Sub
The format for the SID_LOGONRESPONSE/2 password hash:
(DWORD) Client Token
(DWORD) Server Token
(DWORD[5]) Double Hashed Password (Hash plain-text password using the X-SHA-1 hashing functions and then hash the hash along with the client token and the server token)