用VB.net重写了算法
对可注册Code的需求
1、Code的长度为50(Name的长度也为50,Name的后4位为"4612")
2、Code[1]、Code[5] MOD F=4,Code[9] MOD F = 3
3、Code的16字节的MD5 值的 i,F-i,7-i,7+i (i=0,1,2,3)位 XOR 值MD5x,
必须满足 MD5x[i] XOR Code[i] 后,再循环右移 Code[i] MOD 8 位,再加Code[i]等于一固定值(这一步只能穷举?!穷举的数量级不是一般的大)
Dim md5 As New MD5CryptoServiceProvider
Function GetMD5(ByVal TheByte() As Byte) As Byte()
'转换为哈希值Byte数组
Dim mdByte As Byte() = MD5.ComputeHash(TheByte)
'Dim mdString As String = System.BitConverter.ToString(mdByte)
Return mdByte
End Function
Function GetMD5(ByVal TheStr As String) As Byte()
Dim md5 As New MD5CryptoServiceProvider
Dim username As Byte() = (New ASCIIEncoding).GetBytes(TheStr)
'转换为哈希值Byte数组
Dim mdByte As Byte() = md5.ComputeHash(username)
'Dim mdString As String = System.BitConverter.ToString(mdByte)
Return mdByte
End Function
Private Sub ButtonCheck_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonCheck.Click
Me.RegCode = Me.TextBoxCode.Text
Me.RegName = Me.TextBoxName.Text
Me.CalcLenCodeName(Me.RegName.Length, Me.RegCode.Length)
End Sub
'''注册算法
Function CalcLenCodeName(ByVal NameLen As Integer, ByVal CodeLen As Integer) As Boolean
Dim NameLen_add8 As Integer = NameLen + 8
Dim MaxLen As Integer = IIf(NameLen > CodeLen, NameLen, CodeLen) '48、49、50、51
Dim LoopLen As Integer = 4 - (MaxLen Mod 4) + MaxLen '这里要=52
LoopLen = LoopLen \ 4 + 2
If LoopLen <> &HF Then
MessageBox.Show("用户名或注册码的长度有一位必须为50!")
Return False
End If
Dim CodeArray(59) As Byte
''1、CodeLen+4转16进制
CodeArray(0) = CodeLen + 4 Mod 256
CodeArray(1) = (CodeLen + 4) \ 256 Mod 256
CodeArray(2) = (CodeLen + 4) \ 256 \ 256 Mod 256
CodeArray(3) = (CodeLen + 4) \ 256 \ 256 \ 256 Mod 256
'2、复制注册码,CodeArray(0) 循环右移补足
Dim Count As Integer = 0
For i As Integer = 1 To &HF - 1
For j As Integer = 0 To 3
If CodeLen <= Count Then
CodeArray(4 * i + j) = Me.Fun循环右移(CodeArray(0), i + j)
Else
CodeArray(4 * i + j) = Asc(RegCode.Substring(Count, 1))
End If
Count += 1
Next
Next
Dim EBP_2C As Integer
Dim NameArray(3, &HE) As Byte
'3、NameLen+8的 十六进制数
NameArray(0, 0) = (NameLen + 8) Mod 256
NameArray(1, 0) = (NameLen + 8) \ 256 Mod 256
EBP_2C = (NameLen + 8) \ 256 \ 256
NameArray(2, 0) = EBP_2C Mod 256
NameArray(3, 0) = EBP_2C + IIf(EBP_2C < 0, &HFF, 0)
Dim CodeASCStr As String = ""
For i As Integer = 0 To CodeLen - 1
CodeASCStr &= Hex(Asc(Me.RegCode.ToCharArray(i, 1)))
Next
Dim MD5Byte As Byte() = Me.GetMD5(CodeASCStr)
'4、MD5头尾 XOR 第一次,结果取前8字节
For i As Integer = 0 To 7
MD5Byte(i) = MD5Byte(i) Xor MD5Byte(&HF - i)
Next
'5、MD5头尾 XOR 第一次,结果取前4字节
For i As Integer = 0 To 3
NameArray(i, +1) = MD5Byte(i) Xor MD5Byte(&H7 - i)
Next
'6、将Name的ASC放到 NameArray中,NameLen+8 循环右移补足
EBP_2C = 0
For i As Integer = 2 To &HF - 1
For j As Integer = 0 To 3
If EBP_2C >= NameLen Then
NameArray(j, i) = Me.Fun循环右移(NameArray(0, 0), i + j)
Else
NameArray(j, i) = Asc(Me.RegName.Substring(EBP_2C, 1))
End If
EBP_2C += 1
Next
Next
'7、NameArray 与 CodeArray XOR
For i As Integer = 0 To &HF - 1
For j As Integer = 0 To 3
NameArray(j, i) = NameArray(j, i) Xor CodeArray(i * 4 + j)
Next
Next
'8、对NameArray 按CodeArray 按循环右移
For i As Integer = 0 To &HF - 1
For j As Integer = 0 To 3
NameArray(j, i) = Me.Fun循环右移(NameArray(j, i), CodeArray(i * 4 + j))
Next
Next
'9、对NameArray 加 CodeArray
For i As Integer = 0 To &HF - 1
For j As Integer = 0 To 3
NameArray(j, i) = (0 + NameArray(j, i) + CodeArray(i * 4 + j)) And &HFF
Next
Next
'10、对NameArray 每 F位按 CodeArray(1)(5)(9)(13) MOD F 循环右移
For j As Integer = 0 To 3
If j >= &HF Then
EBP_2C = CodeArray(4 * &HF - 3)
Else
EBP_2C = CodeArray(4 * j + 1)
End If
For i As Integer = EBP_2C Mod &HF To 1 Step -1
Dim temp As Integer = NameArray(j, &HF - 1)
For x As Integer = &HF - 1 To 1 Step -1
NameArray(j, x) = NameArray(j, x - 1)
Next
NameArray(j, 0) = temp
Next
Next
'11、对NameArray 头尾交换
For j As Integer = 0 To 1
For i As Integer = 0 To &HF - 1
Dim Temp As Integer = NameArray(3 - j, &HE - i)
NameArray(3 - j, &HE - i) = NameArray(j, i)
NameArray(j, i) = temp
Next
Next
'最后 NameArray为 注册正确
'' 9B 7A 45 44 77 75 28 03 17 7C [2C] 00 DB 36 5F
'' E1 4E D0 B8 0F 33 D1 41 E8 [08] 00 66 F1 EB 7D
'' AB 91 46 62 8E 52 36 A6 B3 [E6] 00 51 4B 94 B4
'' C1 A5 64 03 CF 4B 46 9F 45 03 3E 64 F7 [C7] 66
''[]中的值与Code的MD5值运算,移位等结果
End Function
Function Fun循环右移(ByVal TheValue As Integer, ByVal RLen As Integer)
RLen = RLen Mod 8
Dim V As Integer = (TheValue And (Math.Pow(2, RLen) - 1)) * Math.Pow(2, 8 - RLen) + _
(TheValue \ Math.Pow(2, RLen))
Return V
End Function
'RegCode= 1"34AOCACNADEDABBAFCABBABFEAAAAAACAAADBABDABCDDACA
'RegName= ,}n7JXAyzk`EEc=lIsu)7A+-KK^GU1[I\2<3EC9'JA>}PU4612
'''注册逆算法
Function GetRegName(ByVal CodeLen As Integer) As String
Dim EBP_2C As Integer
Dim NameLen As Integer = 50
Dim NameLen_add8 As Integer ' = NameLen + 8
Dim MaxLen As Integer = CodeLen
Dim LoopLen As Integer = 4 - (MaxLen Mod 4) + MaxLen '这里要=52
LoopLen = LoopLen \ 4 + 2
If LoopLen <> &HF Then
MessageBox.Show("用户名或注册码的长度有一位必须为50!")
Return False
End If
Dim CodeArray(59) As Byte
''1、CodeLen+4转16进制
CodeArray(0) = CodeLen + 4 Mod 256
CodeArray(1) = (CodeLen + 4) \ 256 Mod 256
CodeArray(2) = (CodeLen + 4) \ 256 \ 256 Mod 256
CodeArray(3) = (CodeLen + 4) \ 256 \ 256 \ 256 Mod 256
'2、复制注册,CodeArray(0) 循环右移补足
Dim Count As Integer = 0
For i As Integer = 1 To &HF - 1
For j As Integer = 0 To 3
If CodeLen <= Count Then
CodeArray(4 * i + j) = Me.Fun循环右移(CodeArray(0), i + j)
Else
CodeArray(4 * i + j) = Asc(RegCode.Substring(Count, 1))
End If
Count += 1
Next
Next
'最后 NameArray为 注册正确
'' 9B 7A 45 44 77 75 28 03 17 7C 2C 00 DB 36 5F
'' E1 4E D0 B8 0F 33 D1 41 E8 08 00 66 F1 EB 7D
'' AB 91 46 62 8E 52 36 A6 B3 E6 00 51 4B 94 B4
'' C1 A5 64 03 CF 4B 46 9F 45 03 3E 64 F7 C7 66
Dim NameArray(3, &HE) As Byte
For j As Integer = 0 To 3
For i As Integer = 0 To &HE
NameArray(j, i) = RegArray(&HF * j + i)
Next
Next
[COLOR="Red"] ''Patch NameArray,测试Code的Name
NameArray(0, 10) = &H7A
NameArray(1, 9) = &H7B
NameArray(2, 9) = &H88
NameArray(3, 13) = &H35[/COLOR]
'【正】11、对NameArray 头尾交换
'【逆】一样
For j As Integer = 0 To 1
For i As Integer = 0 To &HF - 1
Dim Temp As Integer = NameArray(3 - j, &HE - i)
NameArray(3 - j, &HE - i) = NameArray(j, i)
NameArray(j, i) = temp
Next
Next
DeBugPrint(NameArray)
' 66 C7 F7 64 3E 03 45 9F 46 4B CF 03 64 A5 C1 CodeArray(1)=0
' B4 94 4B 51 00 E6 B3 A6 36 52 8E 62 46 91 AB 必须将00移到 最前,所以 F - CodeArray(5) Mod F = B => CodeArray(5) Mod F = 4
' 7D EB F1 66 00 08 E8 41 D1 33 0F B8 D0 4E E1 必须将00移到 最前,所以 F - CodeArray(9) Mod F = B => CodeArray(9) Mod F = 4
' 5F 36 DB 00 2C 7C 17 03 28 75 77 44 45 7A 9B 必须将00移到 最前,所以 F - CodeArray(13) Mod F = C => CodeArray(13) Mod F = 3
'【正】10、对NameArray 每 F位 向左 【X= CodeArray(1)(5)(9)(13) MOD F 】循环右移
'【逆】向左 X 移,或向右再移【 F-X】 位
For j As Integer = 0 To 3
If j >= &HF Then
EBP_2C = CodeArray(4 * &HF - 3)
Else
EBP_2C = CodeArray(4 * j + 1)
End If
EBP_2C = &HF - EBP_2C Mod &HF '【逆】结果必须对应为 0 ,4,4,3
For i As Integer = EBP_2C Mod &HF To 1 Step -1
Dim temp As Integer = NameArray(j, &HF - 1)
For x As Integer = &HF - 1 To 1 Step -1
NameArray(j, x) = NameArray(j, x - 1)
Next
NameArray(j, 0) = temp
Next
Next
'逆后的结果必须为
'66 C7 F7 64 3E 03 45 9F 46 4B CF 03 64 A5 C1 '
'00 E6 B3 A6 36 52 8E 62 46 91 AB B4 94 4B 51 '00在最前
'00 08 E8 41 D1 33 0F B8 D0 4E E1 7D EB F1 66 '00在最前
'00 2C 7C 17 03 28 75 77 44 45 7A 9B 5F 36 DB '00在最前
'【正】9、对NameArray 加 CodeArray
'【逆】 减
For i As Integer = 0 To &HF - 1
For j As Integer = 0 To 3
NameArray(j, i) = (0 + NameArray(j, i) - CodeArray(i * 4 + j)) And &HFF
Next
Next
'由上面推的 【 [66 -(CodeLen+4)] 循环右移 [8 - (CodeLen+4) % 8 ] 的结果 XOR (CodeLen + 4)=NameLen+8】
' 且CodeLen=48 、49 、 50 、 51
'=> CodeLen=48 时 NameLen=15 (运算后 最后一字节<>DB)
'=> CodeLen=49 时 NameLen=11 (运算后 最后一字节<>DB)
'=> CodeLen=50 时 NameLen=50
'=> CodeLen=51 时 NameLen=152 (不能大于51)
'【正】8、对NameArray 按CodeArray 按循环右移
'【逆】 循环右移 【8 - CodeArray Mod 8】位
For i As Integer = 0 To &HF - 1
For j As Integer = 0 To 3
NameArray(j, i) = Me.Fun循环右移(NameArray(j, i), 8 - CodeArray(i * 4 + j) Mod 8)
Next
Next
'【正】7、NameArray 与 CodeArray XOR
'【逆】一样
For i As Integer = 0 To &HF - 1
For j As Integer = 0 To 3
NameArray(j, i) = NameArray(j, i) Xor CodeArray(i * 4 + j)
Next
Next
'【正】6、将Name的ASC放到 NameArray中,NameLen+8 循环右移补足
'【逆】后 60-4-4-50=2 位,为 循环右移 8 - (i+j) mod 8 ,其它的Char即为Name
EBP_2C = 0
Dim RegByte(49) As Byte
NameLen = 50
For i As Integer = 2 To &HF - 1
For j As Integer = 0 To 3
If EBP_2C >= NameLen Then
NameArray(j, i) = Me.Fun循环右移(NameArray(0, 0), 8 - (i + j) Mod 8)
Else
'NameArray(j, i) = Asc(Me.RegName.Substring(EBP_2C, 1))
RegByte(EBP_2C) = NameArray(j, i) '''为 用户名
End If
EBP_2C += 1
Next
Next
'RegByte(EBP_2C) = NameArray(j, i) '''为 用户名
Me.TextBoxName.Text = (New ASCIIEncoding).GetString(RegByte)
Dim CodeASCStr As String = ""
For i As Integer = 0 To CodeLen - 1
CodeASCStr &= Hex(Asc(Me.RegCode.Substring(i, 1)))
Next
Dim MD5Byte As Byte() = Me.GetMD5(CodeASCStr)
'4、MD5头尾 XOR 第一次,结果取前8字节
For i As Integer = 0 To 7
MD5Byte(i) = MD5Byte(i) Xor MD5Byte(&HF - i)
Next
'5、MD5头尾 XOR 第一次,结果取前4字节
Dim bln有效Code和Name As Boolean = True
For i As Integer = 0 To 3
'NameArray(i, 1) = MD5Byte(i) Xor MD5Byte(&H7 - i)
If Not (NameArray(i, 1) = (MD5Byte(i) Xor MD5Byte(&H7 - i))) Then
bln有效Code和Name = False
Exit For
End If
Next
If bln有效Code和Name Then
MessageBox.Show("Code和Name有效!")
Else
MessageBox.Show("Code和Name无效!")
End If
'3、NameLen+8的 十六进制数
NameArray(0, 0) = (NameLen + 8) Mod 256
NameArray(1, 0) = (NameLen + 8) \ 256 Mod 256
EBP_2C = (NameLen + 8) \ 256 \ 256
NameArray(2, 0) = EBP_2C Mod 256
NameArray(3, 0) = EBP_2C + IIf(EBP_2C < 0, &HFF, 0)
'-------------------------------------------
End Function
'''穷举符合条件的Code
Function CalcName(ByVal CodeI As Integer) ''初始 时 CodeI=0
If CodeI = 50 Then
'''测试
Dim MD5Byte As Byte() = Me.GetMD5(Code)
' 测试 [MD5(1) XOR MD5(E)] XOR [MD5(6) XOR MD5(9)] 的结果 为 NameArray(1,1)
' 与 CodeArray(5)=>Code(1) 计算 是否能满足 RegArray(1,1)
Dim MD5_0 As Byte = (MD5Byte(0) Xor MD5Byte(&HF)) Xor (MD5Byte(7) Xor MD5Byte(8))
Dim MD5_1 As Byte = (MD5Byte(1) Xor MD5Byte(&HE)) Xor (MD5Byte(6) Xor MD5Byte(9))
Dim MD5_2 As Byte = (MD5Byte(2) Xor MD5Byte(&HD)) Xor (MD5Byte(5) Xor MD5Byte(&HA))
Dim MD5_3 As Byte = (MD5Byte(3) Xor MD5Byte(&HC)) Xor (MD5Byte(4) Xor MD5Byte(&HB))
'Reg = MD5 XOR Code SHR (Code Mod 8) +Code
'Temp = Temp Xor Code(1)
' ((Me.Fun循环右移(MD5_0 Xor Code(0), Code(0) Mod 8) + Code(0)) And &HFF) = CInt("&HC7")
If ((Me.Fun循环右移(MD5_0 Xor Code(0), Code(0) Mod 8) + Code(0)) And &HFF) = CInt("&HC7") AndAlso _
((Me.Fun循环右移(MD5_1 Xor Code(1), Code(1) Mod 8) + Code(1)) And &HFF) = CInt("&HE6") AndAlso _
((Me.Fun循环右移(MD5_2 Xor Code(2), Code(2) Mod 8) + Code(2)) And &HFF) = CInt("&H8") AndAlso _
((Me.Fun循环右移(MD5_3 Xor Code(3), Code(3) Mod 8) + Code(3)) And &HFF) = CInt("&H2C") Then
'''有效KEY
writeKey()
End If
Exit Function
End If
For x As Integer = 33 To 126 '这里只穷举可显示的字符串 ! 到 ~
Select Case CodeI
Case 1, 5 ' Mod F =4
If x Mod &HF = 4 Then
Code(CodeI) = x
CodeI += 1
Me.CalcName(CodeI)
CodeI -= 1
End If
Case 9 ' Mod F=3
If x Mod &HF = 3 Then
Code(CodeI) = x
CodeI += 1
Me.CalcName(CodeI)
CodeI -= 1
End If
Case Else
Code(CodeI) = x
CodeI += 1
Me.CalcName(CodeI)
CodeI -= 1
End Select
Next
End Function