Skip to content

Instantly share code, notes, and snippets.

@AlexanderWingard
Created May 27, 2009 21:18
Show Gist options
  • Save AlexanderWingard/118912 to your computer and use it in GitHub Desktop.
Save AlexanderWingard/118912 to your computer and use it in GitHub Desktop.
Imports System.Text
Imports System.Security.Cryptography
Public Class MSNChallenge
Public Shared Function GetChallengeResponse(ByVal ProductKey As String, ByVal ProductID As String, ByVal ChallengeData As String) As String
'Step 1: Build Hash String
Dim Hash As String = CreateMD5HexString(ChallengeData & ProductKey)
'Step 2: Build Challenge Array
Dim ChallengeArray() As Integer = CreateChallengeArray(ChallengeData, ProductID)
'Step 3: Create 64-bit Key from Challenge Array
Dim Key As Long = Create64BitKey(ChallengeArray, Hash)
'Step 4: Create Challege Response
Dim Response As String = CreateChallengeResponse(Hash, Key)
'Display Info for Debugging purposes
DisplayChallengeInfo(ChallengeData, Hash, Key, Response)
Return Response
End Function
Private Shared Sub DisplayChallengeInfo(ByVal ChallengeData As String, ByVal Hash As String, ByVal Key As Long, ByVal Response As String)
Console.WriteLine("**************************")
Console.WriteLine("***** Challenge Data *****")
Console.WriteLine(String.Empty)
Console.WriteLine("Data: " & ChallengeData & " (" & ChallengeData.Length.ToString & ")")
Console.WriteLine("Hash: " & HAsh & " (" & HAsh.Length.ToString & ")")
Console.WriteLine("Key: " & Key.ToString & " (" & Key.ToString.Length.ToString & ")")
Console.WriteLine("Response: " & Response & " (" & Response.Length.ToString & ")")
Console.WriteLine(String.Empty)
Console.WriteLine("**************************")
Console.WriteLine("**************************")
End Sub
#Region "Challenge Code"
Private Shared Function CreateChallengeArray(ByVal ChallengeData As String, ByVal ProductID As String) As Integer()
Dim Challenge As String = ChallengeData & ProductID
Challenge = Challenge.PadRight(Challenge.Length + (8 - Challenge.Length Mod 8), "0"c)
Dim ChallengeArray(CType((Challenge.Length / 4) - 1, Integer)) As Integer
For Index As Integer = 0 To ChallengeArray.GetUpperBound(0)
Dim ValueString As String = Challenge.Substring(Index * 4, 4)
Dim HexString As String = String.Empty
For Each Item As Char In ValueString
HexString &= String.Format("{0:x2}", Convert.ToInt16(Item))
Next Item
HexString = HexReverse(HexString)
ChallengeArray(Index) = Convert.ToInt32(HexString, 16)
Next Index
Return ChallengeArray
End Function
Private Shared Function CreateHashArray(ByVal Hash As String) As Integer()
Dim HashArray(3) As Integer
For Index As Integer = 0 To HashArray.GetUpperBound(0)
Dim HexString As String = HexReverse(Hash.Substring(Index * 8, 8))
Dim HexValue As Integer = Convert.ToInt32(HexString, 16)
HashArray(Index) = HexValue And &H7FFFFFFF
Next Index
Return HashArray
End Function
Private Shared Function Create64BitKey(ByVal ChallengeArray() As Integer, ByVal Hash As String) As Long
Dim HashArray() As Integer = CreateHashArray(Hash)
Dim High As Long = 0
Dim Low As Long = 0
For Index As Integer = 0 To ChallengeArray.GetUpperBound(0) - 1 Step 2
Dim Temp As Long = ChallengeArray(Index)
Temp = (Temp * &HE79A9C1) Mod &H7FFFFFFF
Temp = Temp + High
Temp = HashArray(0) * Temp + HashArray(1)
Temp = Temp Mod &H7FFFFFFF
High = ChallengeArray(Index + 1)
High = (High + Temp) Mod &H7FFFFFFF
High = HashArray(2) * High + HashArray(3)
High = High Mod &H7FFFFFFF
Low = Low + High + Temp
Next Index
High = (High + HashArray(1)) Mod &H7FFFFFFF
Dim HighHex As String = HexReverse(String.Format("{0:x}", High))
High = Convert.ToInt64(HighHex, 16)
Low = (Low + HashArray(3)) Mod &H7FFFFFFF
Dim LowHex As String = HexReverse(String.Format("{0:x}", Low))
Low = Convert.ToInt64(LowHex, 16)
Dim Key As Long = (High << 32) + Low
Return Key
End Function
Private Shared Function CreateChallengeResponse(ByVal Hash As String, ByVal Key As Long) As String
Dim ResponsePart1 As String = String.Format("{0:x16}", Convert.ToInt64(Hash.Substring(0, 16), 16) Xor Key)
Dim ResponsePart2 As String = String.Format("{0:x16}", Convert.ToInt64(Hash.Substring(16, 16), 16) Xor Key)
Dim HashResponse As String = ResponsePart1 & ResponsePart2
Return HashResponse
End Function
#End Region
#Region "Hex Functions"
Private Shared Function CreateMD5HexString(ByVal Data As String) As String
Dim MD5 As New MD5CryptoServiceProvider
Dim Hash() As Byte = MD5.ComputeHash(Encoding.UTF8.GetBytes(Data))
MD5.Clear()
Dim HashString As New StringBuilder
For Each Item As Byte In Hash
HashString.Append(String.Format("{0:x2}", Item))
Next Item
Return HashString.ToString
End Function
Private Shared Function HexReverse(ByVal HexString As String) As String
Dim Data As String = HexString.PadLeft(HexString.Length + (HexString.Length Mod 2), "0"c)
Dim SwappedString As New StringBuilder
For Index As Integer = Data.Length - 2 To 0 Step -2
SwappedString.Append(Data.Substring(Index, 2))
Next Index
Return SwappedString.ToString
End Function
#End Region
End Class
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment