Author | Message | Time |
---|---|---|
Barabajagal | Ok, I'm trying to find out exactly what the differences are between Standard SHA-1 and Broken SHA-1, using examples from three languages. So far, I've found two things. First is the 0x40 byte null padding. Second is what appears to be byte trimming... by which I mean: [code]for(i = 0x10; i < 0x50; i++) { dw = buf[i-0x10] ^ buf[i-0x8] ^ buf[i-0xE] ^ buf[i-0x3]; buf = (1 >>> (0x20 - (byte)dw)) | (1 << (byte) dw); }[/code] The (byte)dw part. However, these two changes alone don't seem to make Standard SHA into Broken SHA. I've looked over copies of the function in C++, Java, and VB6, but I still seem to be missing things. Would someone [i]please shed some light on this for me? | May 14, 2007, 10:39 PM |
warz | not sure what the problem is. what is 'broken sha1'? are you referring to the implementation that checkrevision uses, or are you referring to any sha1 implementation that has differences from the standard implementation? if so, which specific one? if you're talking about the implementation that checkrevision has in place, the code for it, in C++, has already been made public, and the differences are within sha1final. | May 14, 2007, 10:59 PM |
Barabajagal | I'm talking about the one used in CDKey/Password hashing. That's what Broken SHA-1 has always been... See: Java: https://davnit.net/bnet/vL/index.php?topic=6999.0 VB: https://davnit.net/bnet/vL/index.php?topic=8531.0 | May 14, 2007, 11:01 PM |
warz | [quote author=RεalityRipplε link=topic=16701.msg169026#msg169026 date=1179183719] I'm talking about the one used in CDKey/Password hashing. That's what Broken SHA-1 has always been... [/quote] so, there's a standard broken SHA1 implementation? i would think the term broken would mean any modified SHA1 implementation, considering the amount of people that probably wouldn't honor such a name is probably pretty high. the fact is, there's tons of SHA1 implementations out there, and using the term broken isn't very specific. but, i don't know anything about the pre-lockdown hashing functions. so no help here, sorry. :( | May 14, 2007, 11:07 PM |
l2k-Shadow | [quote author=RεalityRipplε link=topic=16701.msg169026#msg169026 date=1179183719] I'm talking about the one used in CDKey/Password hashing. That's what Broken SHA-1 has always been... [/quote] get yourself source code to bncsutil | May 14, 2007, 11:08 PM |
Barabajagal | [quote author=l2k-Shadow link=topic=16701.msg169028#msg169028 date=1179184100] [quote author=RεalityRipplε link=topic=16701.msg169026#msg169026 date=1179183719] I'm talking about the one used in CDKey/Password hashing. That's what Broken SHA-1 has always been... [/quote] get yourself source code to bncsutil [/quote] Already did that. I'm trying to find the differences, not get a copy of the code. | May 14, 2007, 11:09 PM |
warz | [quote author=RεalityRipplε link=topic=16701.msg169029#msg169029 date=1179184167]Already did that. I'm trying to find the differences, not get a copy of the code.[/quote] isn't that sort of ... what's the word? contradictory. :p now, wouldn't comments help in this scenario, code poet? lol. | May 14, 2007, 11:10 PM |
l2k-Shadow | so just compare the source for the regular hash with the codes you found, I don't understand your question. | May 14, 2007, 11:10 PM |
Barabajagal | I've been comparing them for three days. All I've found is the null-char buffer to 64 bytes and the byte cutoff. | May 14, 2007, 11:13 PM |
warz | [quote author=RεalityRipplε link=topic=16701.msg169032#msg169032 date=1179184425] I've been comparing them for three days. All I've found is the null-char buffer to 64 bytes and the byte cutoff. [/quote] three days? now, doesn't this topic, and the majority of your posts in this topic make for an interesting discussion? | May 14, 2007, 11:16 PM |
Barabajagal | not really? I can read the code just fine. I'm beginning to think it's an endian issue. | May 14, 2007, 11:18 PM |
warz | [quote author=RεalityRipplε link=topic=16701.msg169034#msg169034 date=1179184710] not really? I can read the code just fine. I'm beginning to think it's an endian issue. [/quote] oh, so by read, you've always meant that you can visually see the screen. i always thought by 'read the code' you meant understand what it's telling you. interesting. | May 14, 2007, 11:35 PM |
Barabajagal | *sigh* i don't know why I even bother. I read the code just fine. I understand what it says just fine. If you read through a book looking for the word rendezvous without knowing how it's spelled or what chapter it's in, it takes a while, even if you're a god damn English major (though if you're an English major, wtf are you doing not knowing how to spell rendezvous). Edit: I think I was making it overly complicated. It should instead be something like this... [code] For I = 16 To 79 T = W(I - &H10) Xor W(I - &H8) Xor W(I - &HE) Xor W(I - &H3) If Broken Then W(I) = RoL(1, T) Else W(I) = RoL(T, 1) End If Next I[/code] | May 14, 2007, 11:48 PM |
Quarantine | [quote author=betawarz link=topic=16701.msg169030#msg169030 date=1179184247] [quote author=RεalityRipplε link=topic=16701.msg169029#msg169029 date=1179184167]Already did that. I'm trying to find the differences, not get a copy of the code.[/quote] isn't that sort of ... what's the word? contradictory. :p now, wouldn't comments help in this scenario, code poet? lol. [/quote] WARZ I LOVE YOU. | May 14, 2007, 11:53 PM |
UserLoser | [quote] ... in SHA-1, thereare a number of bit rotate left (ROL) operations. The Blizzard programmer responsible for implementing this apparently switched the two parameters in every call to ROL. That is, if there was a #define ROL(a, b) (...) macro, the programmer swapped the two arguments. This drastically reduces the securityof Battle.net password hashes, as most of the data being hashed ends up being zero bits. Because of the problem of incompatibility with previously created accounts, this system is still in use today. ... [/quote] | May 15, 2007, 4:57 AM |
Barabajagal | That's all I wanted to know. Thank you. Edit: And now, I've got everything but War3 working without BNCSUtil: [code]Option Explicit Private Declare Sub RtlMoveMemory Lib "kernel32" (lpvDest As Any, lpvSource As Any, ByVal cbCopy As Long) Public Function PassHashSingle(ByVal Password As String) As String PassHashSingle = BrokenSHA1(Password) End Function Public Function PassHashDouble(ByVal Password As String, ByVal ClientToken As Long, ByVal ServerToken As Long) As String Dim pHash As String * 20 pHash = BrokenSHA1(Password) PassHashDouble = BrokenSHA1(MakeDWORD(ClientToken) & MakeDWORD(ServerToken) & BrokenSHA1(Password)) End Function Public Function KeyHashAuth(ByVal CDKey As String, ByVal ClientToken As Long, ByVal ServerToken As Long, ByRef KeyProd As Long, ByRef KeyVal1 As Long, ByRef KeyVal2 As Long, ByRef KeyHash As String) As Byte Dim KeyDecoder As Long Dim HashLength As Long Dim HashData As String Dim Ret As Byte If DecodeKey(CDKey, KeyProd, KeyVal1, KeyVal2) Then HashData = MakeDWORD(ClientToken) HashData = HashData & MakeDWORD(ServerToken) HashData = HashData & MakeDWORD(KeyProd) HashData = HashData & MakeDWORD(KeyVal1) HashData = HashData & MakeDWORD(0) HashData = HashData & MakeDWORD(KeyVal2) KeyHash = BrokenSHA1(HashData) KeyHashAuth = 0 Else Ret = bncsutil_HashKey(CDKey, ClientToken, ServerToken, KeyProd, KeyVal1, KeyVal2, KeyHash) If Ret = 0 Then KeyHashAuth = 0 Else KeyHashAuth = Ret End If End If End Function Public Function KeyHashOld(ByVal CDKey As String, ByVal ClientToken As Long, ByVal ServerToken As Long, ByRef KeyProd As Long, ByRef KeyVal1 As Long, ByRef KeyVal2 As Long, ByRef KeyHash As String) As Byte Dim KeyDecoder As Long Dim HashLength As Long Dim HashData As String Dim Ret As Byte Ret = DecodeKey(CDKey, KeyProd, KeyVal1, KeyVal2) If Ret = 0 Then HashData = MakeDWORD(ClientToken) HashData = HashData & MakeDWORD(ServerToken) HashData = HashData & MakeDWORD(KeyProd) HashData = HashData & MakeDWORD(KeyVal1) HashData = HashData & MakeDWORD(KeyVal2) KeyHash = BrokenSHA1(HashData) KeyHashOld = 0 Else Ret = bncsutil_HashKey(CDKey, ClientToken, ServerToken, KeyProd, KeyVal1, KeyVal2, KeyHash) If Ret = 0 Then HashData = MakeDWORD(ClientToken) HashData = HashData & MakeDWORD(ServerToken) HashData = HashData & MakeDWORD(KeyProd) HashData = HashData & MakeDWORD(KeyVal1) HashData = HashData & MakeDWORD(KeyVal2) KeyHash = BrokenSHA1(HashData) KeyHashOld = 0 Else KeyHashOld = Ret End If End If End Function Private Function DecodeKey(ByVal CDKey As String, ByRef KeyProd As Long, ByRef KeyVal1 As Long, ByRef KeyVal2 As Long) As Boolean If Len(CDKey) = 13 Then CDKey = DecodeSTARKey(CDKey) KeyProd = Val("&H" & Left$(CDKey, 2)) If KeyProd = &H1 Or KeyProd = &H2 Then KeyVal1 = Val(Mid$(CDKey, 3, 7)) KeyVal2 = Val(Mid$(CDKey, 10, 3)) DecodeKey = True Else DecodeKey = False End If ElseIf Len(CDKey) = 16 Then CDKey = DecodeD2DVKey(CDKey) KeyProd = Val("&H" & Left$(CDKey, 2)) If KeyProd = &H4 Or KeyProd = &H6 Or KeyProd = &HA Then KeyVal1 = Val("&H" & Mid$(CDKey, 3, 6)) KeyVal2 = Val("&H" & Mid$(CDKey, 9)) DecodeKey = True Else DecodeKey = False End If ElseIf Len(CDKey) = 26 Then 'Warcraft III not in vb6 DecodeKey = False Else DecodeKey = False End If End Function Private Function bncsutil_HashKey(ByVal CDKey As String, ByVal ClientToken As Long, ByVal ServerToken As Long, ByRef KeyProd As Long, ByRef KeyVal1 As Long, ByRef KeyVal2 As Long, ByRef KeyHash As String) As Byte Dim KeyDecoder As Long Dim HashLength As Long kd_init KeyDecoder = kd_create(CDKey, Len(CDKey)) If (KeyDecoder = -1) Then bncsutil_HashKey = 1 kd_free KeyDecoder Exit Function End If HashLength = kd_calculateHash(KeyDecoder, ClientToken, ServerToken) If (HashLength = 0) Then bncsutil_HashKey = 2 kd_free KeyDecoder Exit Function End If If (kd_isValid(KeyDecoder) = 0) Then bncsutil_HashKey = 3 kd_free KeyDecoder Exit Function End If KeyHash = String$(HashLength, vbNullChar) kd_getHash KeyDecoder, KeyHash If Len(KeyHash) <> 20 Then bncsutil_HashKey = 4 kd_free KeyDecoder Exit Function End If KeyProd = kd_product(KeyDecoder) KeyVal1 = kd_val1(KeyDecoder) KeyVal2 = kd_val2(KeyDecoder) kd_free KeyDecoder End Function 'Broken SHA 1 Private Function BrokenSHA1(ByVal buf As String) As String Dim Pos As Long Dim sublen As Long Dim HashBuf(&H10 + 5) As Long Dim I As Long Dim T As String HashBuf(0) = &H67452301 HashBuf(1) = &HEFCDAB89 HashBuf(2) = &H98BADCFE HashBuf(3) = &H10325476 HashBuf(4) = &HC3D2E1F0 For Pos = 0 To Len(buf) Step &H40 sublen = Len(buf) - Pos If sublen > &H40 Then sublen = &H40 T = Mid$(buf, Pos + 1, sublen) & String(&H40 - sublen, Chr$(0)) For I = 0 To 15 HashBuf(5 + I) = GetDWORD(Mid$(T, I * 4 + 1, 4)) Next I BrokenHash HashBuf Next Pos BrokenSHA1 = MakeDWORD(HashBuf(0)) & MakeDWORD(HashBuf(1)) & MakeDWORD(HashBuf(2)) & MakeDWORD(HashBuf(3)) & MakeDWORD(HashBuf(4)) End Function Private Sub BrokenHash(ByRef param() As Long) Dim buf(&H50) As Long Dim A As Long Dim B As Long Dim C As Long Dim D As Long Dim E As Long Dim I As Long Dim P As Long Dim T As Long P = UBound(param) - 5 If P > &H40 Then P = &H40 For I = 0 To P - 1 buf(I) = param(I + 5) Next For I = &H10 To &H4F T = buf(I - &H3) Xor buf(I - &H8) Xor buf(I - &H10) Xor buf(I - &HE) buf(I) = RoL(1, T) Next A = param(0) B = param(1) C = param(2) D = param(3) E = param(4) For I = 0 To 79 T = U32Add(buf(I), E) T = U32Add(T, RoL(A, 5)) Select Case I Case Is < 20 T = U32Add(T, ((B And C) Or ((Not B) And D))) T = U32Add(T, &H5A827999) Case Is < 40 T = U32Add(T, (B Xor C Xor D)) T = U32Add(T, &H6ED9EBA1) Case Is < 60 T = U32Add(T, (B And C) Or (B And D) Or (C And D)) T = U32Add(T, &H8F1BBCDC) Case Is < 80 T = U32Add(T, (B Xor C Xor D)) T = U32Add(T, &HCA62C1D6) Case Else Exit Sub End Select E = D D = C C = RoL(B, &H1E) B = A A = T Next param(0) = U32Add(param(0), A) param(1) = U32Add(param(1), B) param(2) = U32Add(param(2), C) param(3) = U32Add(param(3), D) param(4) = U32Add(param(4), E) End Sub Private Function U32Add(ByVal number1 As Long, ByVal number2 As Long) As Long U32Add = DToL(CDbl(number1) + CDbl(number2)) End Function Private Function RoL(ByVal Number As Long, ByVal Shift As Long) As Long Shift = Shift And &H1F RoL = LShift(Number, Shift) Or RShift(Number, 32 - Shift) End Function Private Function LShift(ByVal pnValue As Long, ByVal pnShift As Long) As Long If pnShift > 31 Then LShift = 0 ElseIf pnShift < 0 Then LShift = 0 ElseIf pnShift = 0 Then LShift = pnValue Else pnValue = pnValue And (2 ^ (32 - pnShift) - 1) LShift = DToL(CDbl(pnValue) * CDbl(DToL(2 ^ pnShift))) End If End Function Private Function RShift(ByVal pnValue As Long, ByVal pnShift As Long) As Long If pnShift > 31 Then RShift = 0 ElseIf pnShift < 0 Then RShift = 0 ElseIf pnShift = 0 Then RShift = pnValue Else If (pnValue And &H80000000) = &H80000000 Then RShift = (pnValue And &H7FFFFFFF) RShift = RShift \ (2 ^ pnShift) RShift = RShift Or (2 ^ (31 - pnShift)) Else RShift = Int(CDbl(pnValue) / CDbl(2 ^ pnShift)) End If If RShift = -1 Then Debug.Assert False End If End Function Private Function DToL(ByVal num As Double) As Long While num > &H7FFFFFFF num = num - 4294967296# Wend While num < &H80000000 num = num + 4294967296# Wend DToL = CLng(num) End Function 'CDKey Decoding Private Function DecodeSTARKey(ByVal sKey As String) As String Dim R As Double Dim N As Double Dim N2 As Double Dim v As Double Dim V2 As Double Dim KeyValue As Double Dim C1 As Byte Dim C2 As Byte Dim C As Byte Dim bValid As Boolean Dim I As Integer Dim aryKey(0 To 12) As String For I = 1 To 13 aryKey(I - 1) = Mid$(sKey, I, 1) Next I v = 3 For I = 0 To 11 C = aryKey(I) N = Val(C) N2 = v * 2 N = N Xor N2 v = v + N Next I v = v Mod 10 If Hex(v) = aryKey(12) Then bValid = True End If v = 194 For I = 11 To 0 Step -1 If v < 7 Then Exit For C = aryKey(I) N = CInt(v / 12) N2 = v Mod 12 v = v - 17 C2 = aryKey(N2) aryKey(I) = C2 aryKey(N2) = C Next I V2 = &H13AC9741 For I = 11 To 0 Step -1 C = UCase$(aryKey(I)) aryKey(I) = C If Asc(C) <= &H37 Then v = V2 C2 = v And &HFF C2 = C2 And 7 C2 = C2 Xor C v = RShift(CLng(v), 3) aryKey(I) = C2 V2 = v ElseIf Asc(C) < 65 Then C2 = CByte(I) C2 = C2 And 1 C2 = C2 Xor C aryKey(I) = C2 End If Next I DecodeSTARKey = Join(aryKey, "") Erase aryKey() End Function Private Function DecodeD2DVKey(ByVal key As String) As String Dim R As Double Dim N As Double Dim N2 As Double Dim v As Double Dim V2 As Double Dim KeyValue As Double Dim C1 As Byte Dim C2 As Byte Dim C As Byte Dim bValid As Boolean Dim I As Integer Dim aryKey(0 To 15) As String Const CodeValues As String = "246789BCDEFGHJKMNPRTVWXZ" R = 1 KeyValue = 0 For I = 1 To 16 aryKey(I - 1) = Mid$(key, I, 1) Next I For I = 0 To 15 Step 2 C1 = InStr(1, CodeValues, aryKey(I)) - 1 If C1 = -1 Then C1 = &HFF N = C1 * 3 C2 = InStr(1, CodeValues, aryKey(I + 1)) - 1 If C2 = -1 Then C2 = &HFF N = C2 + N * 8 If N >= &H100 Then N = N - &H100 KeyValue = KeyValue Or R End If N2 = N N2 = RShift(N2, 4) aryKey(I) = GetHexValue(N2) aryKey(I + 1) = GetHexValue(N) R = LShift(R, 1) Next I v = 3 For I = 0 To 15 C = GetNumValue(aryKey(I)) N = Val(C) N2 = v * 2 N = N Xor N2 v = v + N Next I v = v And &HFF For I = 15 To 0 Step -1 C = Asc(aryKey(I)) If I > 8 Then N = I - 9 Else N = &HF - (8 - I) End If N = N And &HF C2 = Asc(aryKey(N)) aryKey(I) = Chr$(C2) aryKey(N) = Chr$(C) Next I V2 = &H13AC9741 For I = 15 To 0 Step -1 C = Asc(UCase(aryKey(I))) aryKey(I) = Chr$(C) If Val(C) <= &H37 Then v = V2 C2 = v And &HF C2 = C2 And 7 C2 = C2 Xor C v = RShift(v, 3) aryKey(I) = Chr$(C2) V2 = v ElseIf Val(C) < &H41 Then C2 = CByte(I) C2 = C2 And 1 C2 = C2 Xor C aryKey(I) = Chr$(C2) End If Next I DecodeD2DVKey = Join(aryKey, "") Erase aryKey() End Function Private Function GetHexValue(ByVal Val As Long) As String Val = Val And &HF If Val < 10 Then GetHexValue = Chr$(Val + &H30) Else GetHexValue = Chr$(v + &H37) End If End Function Private Function GetNumValue(ByVal Val As String) As Long On Error Resume Next Val = UCase(Val) If IsNumeric(Val) Then GetNumValue = Asc(Val) - &H30 Else GetNumValue = Asc(Val) - &H37 End If End Function Private Function MakeDWORD(FromLong As Long) As String Dim strReturn As String * 4 RtlMoveMemory ByVal strReturn, FromLong, 4 MakeDWORD = strReturn End Function Private Function GetDWORD(ByVal FromStr As String) As Long Dim rVal As Long RtlMoveMemory rVal, ByVal FromStr, 4 GetDWORD = rVal End Function [/code] Decoding Warcraft 3 keys in vb6 seems to be pretty much impossible without those nifty 64 bit integers. I'll probably write a PB dll to deal with that (and NLS) eventually. Thank you to the people who have helped me with this so far. | May 15, 2007, 5:23 AM |
bethra | Why the hell are you porting hashing functions to VB... sigh. | May 15, 2007, 5:48 PM |
Barabajagal | Because I'm tired of using external DLLs. And I've actually almost got war3 working, too. yay -1& instead of 4294967295 | May 15, 2007, 8:05 PM |
Quarantine | [quote author=Sorc.Polgara link=topic=16701.msg169057#msg169057 date=1179251324] Why the hell are you porting hashing functions to VB... sigh. [/quote] Because he obviously fails to see the obvious advantages other programming languages offer over VB. And he has his precious certification. | May 15, 2007, 8:09 PM |
l2k-Shadow | war3 CheckRevision in VB takes what like 20 seconds? | May 15, 2007, 10:40 PM |
Myndfyr | [quote author=Warrior link=topic=16701.msg169069#msg169069 date=1179259787] Because he obviously fails to see the obvious advantages other programming languages offer over VB. And he has his precious certification. [/quote] VB6 has certifications? | May 16, 2007, 12:59 AM |
HeRo | I still love you Reality! | May 16, 2007, 1:35 AM |
Quarantine | [quote author=MyndFyre[vL] link=topic=16701.msg169087#msg169087 date=1179277151] [quote author=Warrior link=topic=16701.msg169069#msg169069 date=1179259787] Because he obviously fails to see the obvious advantages other programming languages offer over VB. And he has his precious certification. [/quote] VB6 has certifications? [/quote] Nothing official I'm sure, just a plaque sent by some no-name company so that he feels better of himself when he writes code..err poetry. | May 16, 2007, 1:37 AM |
Barabajagal | [quote author=Warrior link=topic=16701.msg169091#msg169091 date=1179279426] [quote author=MyndFyre[vL] link=topic=16701.msg169087#msg169087 date=1179277151] [quote author=Warrior link=topic=16701.msg169069#msg169069 date=1179259787] Because he obviously fails to see the obvious advantages other programming languages offer over VB. And he has his precious certification. [/quote] VB6 has certifications? [/quote] Nothing official I'm sure, just a plaque sent by some no-name company so that he feels better of himself when he writes code..err poetry. [/quote] ExpertRating.com | May 16, 2007, 2:42 AM |