SourceSafe登录密码安全研究
声明:本文仅做研究交流用途。请不要非法利用。SourceSafePasswordRecovery仅用来帮助自己忘记密码的人使用,请不要用作非法用途,否则后果自负。-txhak
最近想重装系统,在备份数据时居然忘记了系统中一年多以前安装的SourceSafe的密码。一时冲动,便分析起SourceSafe的登录密码来。
在SourceSafe安装目录中(我安装的是SourceSafe2005),安装文件并不多,其中ssapi.dll格外惹人注目,使用depends打开ssapi.dll文件一看,果然有登录密码相关的API。
使用OllyDbg打开SourceSafe客户端文件ssexp.exe一路跟踪,果然在ssapi模块的5C491F75处,发现密码Hash算法。
这段汇编代码用C#表示如下:
public static ushort HashPassword(string password)
{
ushort hashValue = 0;
string hashPassword = password.ToUpper() + "BrianDavidHarry";
for (int i = 0; i < 0x0f; i++)
{
hashValue += (ushort)((hashPassword[i] ^ 0x96) * (i + 1));
}
return hashValue;
}
在OllyDbg中还可以发现,在 SourceSafe目录\data\um.dat文件中存储了用户名和Hash值。具体格式可以参照我附上的工具。
原来SourceSafe将密码存储存储为(16bit,2byte)长的hash值。密码长度最长是15位,而且不区分大小写。想想这种加密方式就知道太简单了。现在MD5都被王小云教授找出碰撞的规律了。这个Hash算法岂不更容易产生Hash碰撞?带着这样的疑问,以及如何产生Hash碰撞的好奇,开始了我的分析之旅。
1, 16bit存储的Hash值共有65536种可能。
2,15位长度,不区分大小写的密码组合共有3119376532692091019651167124种可能。因为合法的密码字符为"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()_+`-=[]\\;',./{}|:\"<>?"。共68个。共有681 + 682 + 683 + … + 6815 =
= 3119376532692091019651167124种。
3,所以每个Hash值至少对应3119376532692091019651167124/65536 = 47597908518861252130907.701477051种密码。可见这种Hash算法产生冲突的几率是多高。(实际的冲突比例比这个数更高,因为总共只产生了10305种哈希值)。
有这么高的Hash冲突几率。要找回忘记的密码还是很难的,3119376532692091019651167124种密码可能性,穷举尝试估计得上万年了吧。但是要找到一个可用的密码那就简单多了。
现在的问题实际上就是求解一个已知Hash值所对应的一个可用密码就可以了。当然,要找回你原始密码,应该不太可能了。一是高Hash冲突率使得一个Hash值会对应很多个解,你不一定知道原始密码是哪个。二是穷举所有可能性的话,现在家用的计算机还没这么快。不过找到可用解也就解决我们的问题了。要找到可用解,还是需要穷举所有密码,计算密码的Hash值,如果该密码计算出来的Hash值与已知的Hash值相等,那么这个密码就是一个可用解。这种穷举在一般情况下应该可以算出解来,不过如果是一些特殊解,可能很长时间也算不出来。我们可以用密码破解中RainbowTable的概念,通过空间换时间,在只需要一次性计算好所有Hash值对应的一个可用密码表。就可以每次查表得到已知Hash值的一个可以密码。由于Hash值一共才65536种可能,因此存储空间也不大。
:)其他方法就当我抛砖引玉,留个大家了。
我使用RainbowTable实现了这个求解的算法,优化后发现生成所有Hash值的RainbowTable都只需要30ms左右。因此相当快,每次自动生成这个RainbowTable都可以,不用事先计算好。:)
internal class RainbowTableHelper
{
#region Instance Data
private static string[] _default = null;
public static readonly string DefaultValidPasswordChars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ~!@#$%^&*()_+`-=[]\\;',./{}|:\"<>?";
public static readonly string TailPassword = "BrianDavidHarry";
public const int PasswordMaxLength = 0x0f;
#endregion
#region Constructor
static RainbowTableHelper()
{
_default = GenerateRainbowTable(DefaultValidPasswordChars);
}
#endregion
#region Properties
public static string[] Default
{
get
{
return _default;
}
}
#endregion
#region Methods
#region Load/Save
public static string[] LoadFrom(string path)
{
using (FileStream stream = new FileStream(path, FileMode.Open))
{
return LoadFrom(stream);
}
}
public static string[] LoadFrom(Stream stream)
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
return binaryFormatter.Deserialize(stream) as string[];
}
public static void SaveTo(string path, string[] rainbowTable)
{
using (FileStream stream = new FileStream(path, FileMode.OpenOrCreate))
{
SaveTo(stream, rainbowTable);
}
}
public static void SaveTo(Stream stream, string[] rainbowTable)
{
BinaryFormatter binaryFormatter = new BinaryFormatter();
binaryFormatter.Serialize(stream, rainbowTable);
}
#endregion
#region GenerateRainbowTable
public static string[] GenerateRainbowTable(string validPasswordChars)
{
string[] rainbowTable = new string[ushort.MaxValue + 1];
ushort[,] xorValues = new ushort[validPasswordChars.Length, PasswordMaxLength + 1];
for (int i = 0; i < validPasswordChars.Length; i++)
{
ushort xorValue = (ushort)(validPasswordChars[i] ^ 0x96);
xorValues[i, 0] = xorValue;
for (int j = 1; j <= PasswordMaxLength; j++)
{
xorValues[i, j] = (ushort)(xorValue * j);
}
}
ushort[,] xorTailPasswordValues = new ushort[TailPassword.Length, PasswordMaxLength + 1];
for (int i = 0; i < TailPassword.Length; i++)
{
ushort xorValue = (ushort)(TailPassword[i] ^ 0x96);
xorTailPasswordValues[i, 0] = xorValue;
for (int j = 1; j <= PasswordMaxLength; j++)
{
xorTailPasswordValues[i, j] = (ushort)(xorValue * j);
}
}
GenerateRainbowTable1(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
GenerateRainbowTable2(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
GenerateRainbowTable3(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
GenerateRainbowTable4(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
GenerateRainbowTable5(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
GenerateRainbowTable6(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
GenerateRainbowTable7(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
GenerateRainbowTable8(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
GenerateRainbowTable9(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
GenerateRainbowTable10(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
GenerateRainbowTable11(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
GenerateRainbowTable12(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
GenerateRainbowTable13(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
GenerateRainbowTable14(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
GenerateRainbowTable15(validPasswordChars, rainbowTable, xorValues, xorTailPasswordValues);
return rainbowTable;
}
private static void GenerateRainbowTable1(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 1;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
ushort computerHashValue = (ushort)(tailPasswordHash + xorValues[i1, 1]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1] });
}
}
}
private static void GenerateRainbowTable2(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 2;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
bool[,] rainbowMasks = new bool[ushort.MaxValue, PasswordLength];
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
int hashValue1 = tailPasswordHash + xorValues[i1, 1];
if (rainbowMasks[hashValue1, 1]) continue;
rainbowMasks[hashValue1, 1] = true;
for (int i2 = 0; i2 < length; i2++)
{
ushort computerHashValue = (ushort)(hashValue1 + xorValues[i2, 2]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1], validPasswordChars[i2] });
}
}
}
}
private static void GenerateRainbowTable3(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 3;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
bool[,] rainbowMasks = new bool[ushort.MaxValue, PasswordLength];
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
int hashValue1 = tailPasswordHash + xorValues[i1, 1];
if (rainbowMasks[hashValue1, 1]) continue;
rainbowMasks[hashValue1, 1] = true;
for (int i2 = 0; i2 < length; i2++)
{
int hashValue2 = hashValue1 + xorValues[i2, 2];
if (rainbowMasks[hashValue2, 2]) continue;
rainbowMasks[hashValue2, 2] = true;
for (int i3 = 0; i3 < length; i3++)
{
ushort computerHashValue = (ushort)(hashValue2 + xorValues[i3, 3]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1], validPasswordChars[i2], validPasswordChars[i3] });
}
}
}
}
}
private static void GenerateRainbowTable4(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 4;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
bool[,] rainbowMasks = new bool[ushort.MaxValue, PasswordLength];
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
int hashValue1 = tailPasswordHash + xorValues[i1, 1];
if (rainbowMasks[hashValue1, 1]) continue;
rainbowMasks[hashValue1, 1] = true;
for (int i2 = 0; i2 < length; i2++)
{
int hashValue2 = hashValue1 + xorValues[i2, 2];
if (rainbowMasks[hashValue2, 2]) continue;
rainbowMasks[hashValue2, 2] = true;
for (int i3 = 0; i3 < length; i3++)
{
int hashValue3 = hashValue2 + xorValues[i3, 3];
if (rainbowMasks[hashValue3, 3]) continue;
rainbowMasks[hashValue3, 3] = true;
for (int i4 = 0; i4 < length; i4++)
{
ushort computerHashValue = (ushort)(hashValue3 + xorValues[i4, 4]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1], validPasswordChars[i2], validPasswordChars[i3], validPasswordChars[i4] });
}
}
}
}
}
}
private static void GenerateRainbowTable5(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 5;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
bool[,] rainbowMasks = new bool[ushort.MaxValue, PasswordLength];
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
int hashValue1 = tailPasswordHash + xorValues[i1, 1];
if (rainbowMasks[hashValue1, 1]) continue;
rainbowMasks[hashValue1, 1] = true;
for (int i2 = 0; i2 < length; i2++)
{
int hashValue2 = hashValue1 + xorValues[i2, 2];
if (rainbowMasks[hashValue2, 2]) continue;
rainbowMasks[hashValue2, 2] = true;
for (int i3 = 0; i3 < length; i3++)
{
int hashValue3 = hashValue2 + xorValues[i3, 3];
if (rainbowMasks[hashValue3, 3]) continue;
rainbowMasks[hashValue3, 3] = true;
for (int i4 = 0; i4 < length; i4++)
{
int hashValue4 = hashValue3 + xorValues[i4, 4];
if (rainbowMasks[hashValue4, 4]) continue;
rainbowMasks[hashValue4, 4] = true;
for (int i5 = 0; i5 < length; i5++)
{
ushort computerHashValue = (ushort)(hashValue4 + xorValues[i5, 5]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1], validPasswordChars[i2], validPasswordChars[i3], validPasswordChars[i4], validPasswordChars[i5] });
}
}
}
}
}
}
}
private static void GenerateRainbowTable6(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 6;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
bool[,] rainbowMasks = new bool[ushort.MaxValue, PasswordLength];
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
int hashValue1 = tailPasswordHash + xorValues[i1, 1];
if (rainbowMasks[hashValue1, 1]) continue;
rainbowMasks[hashValue1, 1] = true;
for (int i2 = 0; i2 < length; i2++)
{
int hashValue2 = hashValue1 + xorValues[i2, 2];
if (rainbowMasks[hashValue2, 2]) continue;
rainbowMasks[hashValue2, 2] = true;
for (int i3 = 0; i3 < length; i3++)
{
int hashValue3 = hashValue2 + xorValues[i3, 3];
if (rainbowMasks[hashValue3, 3]) continue;
rainbowMasks[hashValue3, 3] = true;
for (int i4 = 0; i4 < length; i4++)
{
int hashValue4 = hashValue3 + xorValues[i4, 4];
if (rainbowMasks[hashValue4, 4]) continue;
rainbowMasks[hashValue4, 4] = true;
for (int i5 = 0; i5 < length; i5++)
{
int hashValue5 = hashValue4 + xorValues[i5, 5];
if (rainbowMasks[hashValue5, 5]) continue;
rainbowMasks[hashValue5, 5] = true;
for (int i6 = 0; i6 < length; i6++)
{
ushort computerHashValue = (ushort)(hashValue5 + xorValues[i6, 6]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1], validPasswordChars[i2], validPasswordChars[i3], validPasswordChars[i4], validPasswordChars[i5], validPasswordChars[i6] });
}
}
}
}
}
}
}
}
private static void GenerateRainbowTable7(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 7;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
bool[,] rainbowMasks = new bool[ushort.MaxValue, PasswordLength];
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
int hashValue1 = tailPasswordHash + xorValues[i1, 1];
if (rainbowMasks[hashValue1, 1]) continue;
rainbowMasks[hashValue1, 1] = true;
for (int i2 = 0; i2 < length; i2++)
{
int hashValue2 = hashValue1 + xorValues[i2, 2];
if (rainbowMasks[hashValue2, 2]) continue;
rainbowMasks[hashValue2, 2] = true;
for (int i3 = 0; i3 < length; i3++)
{
int hashValue3 = hashValue2 + xorValues[i3, 3];
if (rainbowMasks[hashValue3, 3]) continue;
rainbowMasks[hashValue3, 3] = true;
for (int i4 = 0; i4 < length; i4++)
{
int hashValue4 = hashValue3 + xorValues[i4, 4];
if (rainbowMasks[hashValue4, 4]) continue;
rainbowMasks[hashValue4, 4] = true;
for (int i5 = 0; i5 < length; i5++)
{
int hashValue5 = hashValue4 + xorValues[i5, 5];
if (rainbowMasks[hashValue5, 5]) continue;
rainbowMasks[hashValue5, 5] = true;
for (int i6 = 0; i6 < length; i6++)
{
int hashValue6 = hashValue5 + xorValues[i6, 6];
if (rainbowMasks[hashValue6, 6]) continue;
rainbowMasks[hashValue6, 6] = true;
for (int i7 = 0; i7 < length; i7++)
{
ushort computerHashValue = (ushort)(hashValue6 + xorValues[i7, 7]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1], validPasswordChars[i2], validPasswordChars[i3], validPasswordChars[i4], validPasswordChars[i5], validPasswordChars[i6], validPasswordChars[i7] });
}
}
}
}
}
}
}
}
}
private static void GenerateRainbowTable8(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 8;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
bool[,] rainbowMasks = new bool[ushort.MaxValue, PasswordLength];
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
int hashValue1 = tailPasswordHash + xorValues[i1, 1];
if (rainbowMasks[hashValue1, 1]) continue;
rainbowMasks[hashValue1, 1] = true;
for (int i2 = 0; i2 < length; i2++)
{
int hashValue2 = hashValue1 + xorValues[i2, 2];
if (rainbowMasks[hashValue2, 2]) continue;
rainbowMasks[hashValue2, 2] = true;
for (int i3 = 0; i3 < length; i3++)
{
int hashValue3 = hashValue2 + xorValues[i3, 3];
if (rainbowMasks[hashValue3, 3]) continue;
rainbowMasks[hashValue3, 3] = true;
for (int i4 = 0; i4 < length; i4++)
{
int hashValue4 = hashValue3 + xorValues[i4, 4];
if (rainbowMasks[hashValue4, 4]) continue;
rainbowMasks[hashValue4, 4] = true;
for (int i5 = 0; i5 < length; i5++)
{
int hashValue5 = hashValue4 + xorValues[i5, 5];
if (rainbowMasks[hashValue5, 5]) continue;
rainbowMasks[hashValue5, 5] = true;
for (int i6 = 0; i6 < length; i6++)
{
int hashValue6 = hashValue5 + xorValues[i6, 6];
if (rainbowMasks[hashValue6, 6]) continue;
rainbowMasks[hashValue6, 6] = true;
for (int i7 = 0; i7 < length; i7++)
{
int hashValue7 = hashValue6 + xorValues[i7, 7];
if (rainbowMasks[hashValue7, 7]) continue;
rainbowMasks[hashValue7, 7] = true;
for (int i8 = 0; i8 < length; i8++)
{
ushort computerHashValue = (ushort)(hashValue7 + xorValues[i8, 8]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1], validPasswordChars[i2], validPasswordChars[i3], validPasswordChars[i4], validPasswordChars[i5], validPasswordChars[i6], validPasswordChars[i7], validPasswordChars[i8] });
}
}
}
}
}
}
}
}
}
}
private static void GenerateRainbowTable9(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 9;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
bool[,] rainbowMasks = new bool[ushort.MaxValue, PasswordLength];
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
int hashValue1 = tailPasswordHash + xorValues[i1, 1];
if (rainbowMasks[hashValue1, 1]) continue;
rainbowMasks[hashValue1, 1] = true;
for (int i2 = 0; i2 < length; i2++)
{
int hashValue2 = hashValue1 + xorValues[i2, 2];
if (rainbowMasks[hashValue2, 2]) continue;
rainbowMasks[hashValue2, 2] = true;
for (int i3 = 0; i3 < length; i3++)
{
int hashValue3 = hashValue2 + xorValues[i3, 3];
if (rainbowMasks[hashValue3, 3]) continue;
rainbowMasks[hashValue3, 3] = true;
for (int i4 = 0; i4 < length; i4++)
{
int hashValue4 = hashValue3 + xorValues[i4, 4];
if (rainbowMasks[hashValue4, 4]) continue;
rainbowMasks[hashValue4, 4] = true;
for (int i5 = 0; i5 < length; i5++)
{
int hashValue5 = hashValue4 + xorValues[i5, 5];
if (rainbowMasks[hashValue5, 5]) continue;
rainbowMasks[hashValue5, 5] = true;
for (int i6 = 0; i6 < length; i6++)
{
int hashValue6 = hashValue5 + xorValues[i6, 6];
if (rainbowMasks[hashValue6, 6]) continue;
rainbowMasks[hashValue6, 6] = true;
for (int i7 = 0; i7 < length; i7++)
{
int hashValue7 = hashValue6 + xorValues[i7, 7];
if (rainbowMasks[hashValue7, 7]) continue;
rainbowMasks[hashValue7, 7] = true;
for (int i8 = 0; i8 < length; i8++)
{
int hashValue8 = hashValue7 + xorValues[i8, 8];
if (rainbowMasks[hashValue8, 8]) continue;
rainbowMasks[hashValue8, 8] = true;
for (int i9 = 0; i9 < length; i9++)
{
ushort computerHashValue = (ushort)(hashValue8 + xorValues[i9, 9]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1], validPasswordChars[i2], validPasswordChars[i3], validPasswordChars[i4], validPasswordChars[i5], validPasswordChars[i6], validPasswordChars[i7], validPasswordChars[i8], validPasswordChars[i9] });
}
}
}
}
}
}
}
}
}
}
}
private static void GenerateRainbowTable10(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 10;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
bool[,] rainbowMasks = new bool[ushort.MaxValue, PasswordLength];
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
int hashValue1 = tailPasswordHash + xorValues[i1, 1];
if (rainbowMasks[hashValue1, 1]) continue;
rainbowMasks[hashValue1, 1] = true;
for (int i2 = 0; i2 < length; i2++)
{
int hashValue2 = hashValue1 + xorValues[i2, 2];
if (rainbowMasks[hashValue2, 2]) continue;
rainbowMasks[hashValue2, 2] = true;
for (int i3 = 0; i3 < length; i3++)
{
int hashValue3 = hashValue2 + xorValues[i3, 3];
if (rainbowMasks[hashValue3, 3]) continue;
rainbowMasks[hashValue3, 3] = true;
for (int i4 = 0; i4 < length; i4++)
{
int hashValue4 = hashValue3 + xorValues[i4, 4];
if (rainbowMasks[hashValue4, 4]) continue;
rainbowMasks[hashValue4, 4] = true;
for (int i5 = 0; i5 < length; i5++)
{
int hashValue5 = hashValue4 + xorValues[i5, 5];
if (rainbowMasks[hashValue5, 5]) continue;
rainbowMasks[hashValue5, 5] = true;
for (int i6 = 0; i6 < length; i6++)
{
int hashValue6 = hashValue5 + xorValues[i6, 6];
if (rainbowMasks[hashValue6, 6]) continue;
rainbowMasks[hashValue6, 6] = true;
for (int i7 = 0; i7 < length; i7++)
{
int hashValue7 = hashValue6 + xorValues[i7, 7];
if (rainbowMasks[hashValue7, 7]) continue;
rainbowMasks[hashValue7, 7] = true;
for (int i8 = 0; i8 < length; i8++)
{
int hashValue8 = hashValue7 + xorValues[i8, 8];
if (rainbowMasks[hashValue8, 8]) continue;
rainbowMasks[hashValue8, 8] = true;
for (int i9 = 0; i9 < length; i9++)
{
int hashValue9 = hashValue8 + xorValues[i9, 9];
if (rainbowMasks[hashValue9, 9]) continue;
rainbowMasks[hashValue9, 9] = true;
for (int i10 = 0; i10 < length; i10++)
{
ushort computerHashValue = (ushort)(hashValue9 + xorValues[i10, 10]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1], validPasswordChars[i2], validPasswordChars[i3], validPasswordChars[i4], validPasswordChars[i5], validPasswordChars[i6], validPasswordChars[i7], validPasswordChars[i8], validPasswordChars[i9], validPasswordChars[i10] });
}
}
}
}
}
}
}
}
}
}
}
}
private static void GenerateRainbowTable11(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 11;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
bool[,] rainbowMasks = new bool[ushort.MaxValue, PasswordLength];
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
int hashValue1 = tailPasswordHash + xorValues[i1, 1];
if (rainbowMasks[hashValue1, 1]) continue;
rainbowMasks[hashValue1, 1] = true;
for (int i2 = 0; i2 < length; i2++)
{
int hashValue2 = hashValue1 + xorValues[i2, 2];
if (rainbowMasks[hashValue2, 2]) continue;
rainbowMasks[hashValue2, 2] = true;
for (int i3 = 0; i3 < length; i3++)
{
int hashValue3 = hashValue2 + xorValues[i3, 3];
if (rainbowMasks[hashValue3, 3]) continue;
rainbowMasks[hashValue3, 3] = true;
for (int i4 = 0; i4 < length; i4++)
{
int hashValue4 = hashValue3 + xorValues[i4, 4];
if (rainbowMasks[hashValue4, 4]) continue;
rainbowMasks[hashValue4, 4] = true;
for (int i5 = 0; i5 < length; i5++)
{
int hashValue5 = hashValue4 + xorValues[i5, 5];
if (rainbowMasks[hashValue5, 5]) continue;
rainbowMasks[hashValue5, 5] = true;
for (int i6 = 0; i6 < length; i6++)
{
int hashValue6 = hashValue5 + xorValues[i6, 6];
if (rainbowMasks[hashValue6, 6]) continue;
rainbowMasks[hashValue6, 6] = true;
for (int i7 = 0; i7 < length; i7++)
{
int hashValue7 = hashValue6 + xorValues[i7, 7];
if (rainbowMasks[hashValue7, 7]) continue;
rainbowMasks[hashValue7, 7] = true;
for (int i8 = 0; i8 < length; i8++)
{
int hashValue8 = hashValue7 + xorValues[i8, 8];
if (rainbowMasks[hashValue8, 8]) continue;
rainbowMasks[hashValue8, 8] = true;
for (int i9 = 0; i9 < length; i9++)
{
int hashValue9 = hashValue8 + xorValues[i9, 9];
if (rainbowMasks[hashValue9, 9]) continue;
rainbowMasks[hashValue9, 9] = true;
for (int i10 = 0; i10 < length; i10++)
{
int hashValue10 = hashValue9 + xorValues[i10, 10];
if (rainbowMasks[hashValue10, 10]) continue;
rainbowMasks[hashValue10, 10] = true;
for (int i11 = 0; i11 < length; i11++)
{
ushort computerHashValue = (ushort)(hashValue10 + xorValues[i11, 11]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1], validPasswordChars[i2], validPasswordChars[i3], validPasswordChars[i4], validPasswordChars[i5], validPasswordChars[i6], validPasswordChars[i7], validPasswordChars[i8], validPasswordChars[i9], validPasswordChars[i10], validPasswordChars[i11] });
}
}
}
}
}
}
}
}
}
}
}
}
}
private static void GenerateRainbowTable12(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 12;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
bool[,] rainbowMasks = new bool[ushort.MaxValue, PasswordLength];
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
int hashValue1 = tailPasswordHash + xorValues[i1, 1];
if (rainbowMasks[hashValue1, 1]) continue;
rainbowMasks[hashValue1, 1] = true;
for (int i2 = 0; i2 < length; i2++)
{
int hashValue2 = hashValue1 + xorValues[i2, 2];
if (rainbowMasks[hashValue2, 2]) continue;
rainbowMasks[hashValue2, 2] = true;
for (int i3 = 0; i3 < length; i3++)
{
int hashValue3 = hashValue2 + xorValues[i3, 3];
if (rainbowMasks[hashValue3, 3]) continue;
rainbowMasks[hashValue3, 3] = true;
for (int i4 = 0; i4 < length; i4++)
{
int hashValue4 = hashValue3 + xorValues[i4, 4];
if (rainbowMasks[hashValue4, 4]) continue;
rainbowMasks[hashValue4, 4] = true;
for (int i5 = 0; i5 < length; i5++)
{
int hashValue5 = hashValue4 + xorValues[i5, 5];
if (rainbowMasks[hashValue5, 5]) continue;
rainbowMasks[hashValue5, 5] = true;
for (int i6 = 0; i6 < length; i6++)
{
int hashValue6 = hashValue5 + xorValues[i6, 6];
if (rainbowMasks[hashValue6, 6]) continue;
rainbowMasks[hashValue6, 6] = true;
for (int i7 = 0; i7 < length; i7++)
{
int hashValue7 = hashValue6 + xorValues[i7, 7];
if (rainbowMasks[hashValue7, 7]) continue;
rainbowMasks[hashValue7, 7] = true;
for (int i8 = 0; i8 < length; i8++)
{
int hashValue8 = hashValue7 + xorValues[i8, 8];
if (rainbowMasks[hashValue8, 8]) continue;
rainbowMasks[hashValue8, 8] = true;
for (int i9 = 0; i9 < length; i9++)
{
int hashValue9 = hashValue8 + xorValues[i9, 9];
if (rainbowMasks[hashValue9, 9]) continue;
rainbowMasks[hashValue9, 9] = true;
for (int i10 = 0; i10 < length; i10++)
{
int hashValue10 = hashValue9 + xorValues[i10, 10];
if (rainbowMasks[hashValue10, 10]) continue;
rainbowMasks[hashValue10, 10] = true;
for (int i11 = 0; i11 < length; i11++)
{
int hashValue11 = hashValue10 + xorValues[i11, 11];
if (rainbowMasks[hashValue11, 11]) continue;
rainbowMasks[hashValue11, 11] = true;
for (int i12 = 0; i12 < length; i12++)
{
ushort computerHashValue = (ushort)(hashValue11 + xorValues[i12, 12]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1], validPasswordChars[i2], validPasswordChars[i3], validPasswordChars[i4], validPasswordChars[i5], validPasswordChars[i6], validPasswordChars[i7], validPasswordChars[i8], validPasswordChars[i9], validPasswordChars[i10], validPasswordChars[i11], validPasswordChars[i12] });
}
}
}
}
}
}
}
}
}
}
}
}
}
}
private static void GenerateRainbowTable13(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 13;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
bool[,] rainbowMasks = new bool[ushort.MaxValue, PasswordLength];
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
int hashValue1 = tailPasswordHash + xorValues[i1, 1];
if (rainbowMasks[hashValue1, 1]) continue;
rainbowMasks[hashValue1, 1] = true;
for (int i2 = 0; i2 < length; i2++)
{
int hashValue2 = hashValue1 + xorValues[i2, 2];
if (rainbowMasks[hashValue2, 2]) continue;
rainbowMasks[hashValue2, 2] = true;
for (int i3 = 0; i3 < length; i3++)
{
int hashValue3 = hashValue2 + xorValues[i3, 3];
if (rainbowMasks[hashValue3, 3]) continue;
rainbowMasks[hashValue3, 3] = true;
for (int i4 = 0; i4 < length; i4++)
{
int hashValue4 = hashValue3 + xorValues[i4, 4];
if (rainbowMasks[hashValue4, 4]) continue;
rainbowMasks[hashValue4, 4] = true;
for (int i5 = 0; i5 < length; i5++)
{
int hashValue5 = hashValue4 + xorValues[i5, 5];
if (rainbowMasks[hashValue5, 5]) continue;
rainbowMasks[hashValue5, 5] = true;
for (int i6 = 0; i6 < length; i6++)
{
int hashValue6 = hashValue5 + xorValues[i6, 6];
if (rainbowMasks[hashValue6, 6]) continue;
rainbowMasks[hashValue6, 6] = true;
for (int i7 = 0; i7 < length; i7++)
{
int hashValue7 = hashValue6 + xorValues[i7, 7];
if (rainbowMasks[hashValue7, 7]) continue;
rainbowMasks[hashValue7, 7] = true;
for (int i8 = 0; i8 < length; i8++)
{
int hashValue8 = hashValue7 + xorValues[i8, 8];
if (rainbowMasks[hashValue8, 8]) continue;
rainbowMasks[hashValue8, 8] = true;
for (int i9 = 0; i9 < length; i9++)
{
int hashValue9 = hashValue8 + xorValues[i9, 9];
if (rainbowMasks[hashValue9, 9]) continue;
rainbowMasks[hashValue9, 9] = true;
for (int i10 = 0; i10 < length; i10++)
{
int hashValue10 = hashValue9 + xorValues[i10, 10];
if (rainbowMasks[hashValue10, 10]) continue;
rainbowMasks[hashValue10, 10] = true;
for (int i11 = 0; i11 < length; i11++)
{
int hashValue11 = hashValue10 + xorValues[i11, 11];
if (rainbowMasks[hashValue11, 11]) continue;
rainbowMasks[hashValue11, 11] = true;
for (int i12 = 0; i12 < length; i12++)
{
int hashValue12 = hashValue11 + xorValues[i12, 12];
if (rainbowMasks[hashValue12, 12]) continue;
rainbowMasks[hashValue12, 12] = true;
for (int i13 = 0; i13 < length; i13++)
{
ushort computerHashValue = (ushort)(hashValue12 + xorValues[i13, 13]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1], validPasswordChars[i2], validPasswordChars[i3], validPasswordChars[i4], validPasswordChars[i5], validPasswordChars[i6], validPasswordChars[i7], validPasswordChars[i8], validPasswordChars[i9], validPasswordChars[i10], validPasswordChars[i11], validPasswordChars[i12], validPasswordChars[i13] });
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
private static void GenerateRainbowTable14(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 14;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
bool[,] rainbowMasks = new bool[ushort.MaxValue, PasswordLength];
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
int hashValue1 = tailPasswordHash + xorValues[i1, 1];
if (rainbowMasks[hashValue1, 1]) continue;
rainbowMasks[hashValue1, 1] = true;
for (int i2 = 0; i2 < length; i2++)
{
int hashValue2 = hashValue1 + xorValues[i2, 2];
if (rainbowMasks[hashValue2, 2]) continue;
rainbowMasks[hashValue2, 2] = true;
for (int i3 = 0; i3 < length; i3++)
{
int hashValue3 = hashValue2 + xorValues[i3, 3];
if (rainbowMasks[hashValue3, 3]) continue;
rainbowMasks[hashValue3, 3] = true;
for (int i4 = 0; i4 < length; i4++)
{
int hashValue4 = hashValue3 + xorValues[i4, 4];
if (rainbowMasks[hashValue4, 4]) continue;
rainbowMasks[hashValue4, 4] = true;
for (int i5 = 0; i5 < length; i5++)
{
int hashValue5 = hashValue4 + xorValues[i5, 5];
if (rainbowMasks[hashValue5, 5]) continue;
rainbowMasks[hashValue5, 5] = true;
for (int i6 = 0; i6 < length; i6++)
{
int hashValue6 = hashValue5 + xorValues[i6, 6];
if (rainbowMasks[hashValue6, 6]) continue;
rainbowMasks[hashValue6, 6] = true;
for (int i7 = 0; i7 < length; i7++)
{
int hashValue7 = hashValue6 + xorValues[i7, 7];
if (rainbowMasks[hashValue7, 7]) continue;
rainbowMasks[hashValue7, 7] = true;
for (int i8 = 0; i8 < length; i8++)
{
int hashValue8 = hashValue7 + xorValues[i8, 8];
if (rainbowMasks[hashValue8, 8]) continue;
rainbowMasks[hashValue8, 8] = true;
for (int i9 = 0; i9 < length; i9++)
{
int hashValue9 = hashValue8 + xorValues[i9, 9];
if (rainbowMasks[hashValue9, 9]) continue;
rainbowMasks[hashValue9, 9] = true;
for (int i10 = 0; i10 < length; i10++)
{
int hashValue10 = hashValue9 + xorValues[i10, 10];
if (rainbowMasks[hashValue10, 10]) continue;
rainbowMasks[hashValue10, 10] = true;
for (int i11 = 0; i11 < length; i11++)
{
int hashValue11 = hashValue10 + xorValues[i11, 11];
if (rainbowMasks[hashValue11, 11]) continue;
rainbowMasks[hashValue11, 11] = true;
for (int i12 = 0; i12 < length; i12++)
{
int hashValue12 = hashValue11 + xorValues[i12, 12];
if (rainbowMasks[hashValue12, 12]) continue;
rainbowMasks[hashValue12, 12] = true;
for (int i13 = 0; i13 < length; i13++)
{
int hashValue13 = hashValue12 + xorValues[i13, 13];
if (rainbowMasks[hashValue13, 13]) continue;
rainbowMasks[hashValue13, 13] = true;
for (int i14 = 0; i14 < length; i14++)
{
ushort computerHashValue = (ushort)(hashValue13 + xorValues[i14, 14]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1], validPasswordChars[i2], validPasswordChars[i3], validPasswordChars[i4], validPasswordChars[i5], validPasswordChars[i6], validPasswordChars[i7], validPasswordChars[i8], validPasswordChars[i9], validPasswordChars[i10], validPasswordChars[i11], validPasswordChars[i12], validPasswordChars[i13], validPasswordChars[i14] });
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
private static void GenerateRainbowTable15(string validPasswordChars, string[] rainbowTable, ushort[,] xorValues, ushort[,] xorTailPasswordValues)
{
const int PasswordLength = 15;
ushort tailPasswordHash = GetTailPasswordHash(PasswordMaxLength - PasswordLength, xorTailPasswordValues);
bool[,] rainbowMasks = new bool[ushort.MaxValue, PasswordLength];
int length = validPasswordChars.Length;
for (int i1 = 0; i1 < length; i1++)
{
int hashValue1 = tailPasswordHash + xorValues[i1, 1];
if (rainbowMasks[hashValue1, 1]) continue;
rainbowMasks[hashValue1, 1] = true;
for (int i2 = 0; i2 < length; i2++)
{
int hashValue2 = hashValue1 + xorValues[i2, 2];
if (rainbowMasks[hashValue2, 2]) continue;
rainbowMasks[hashValue2, 2] = true;
for (int i3 = 0; i3 < length; i3++)
{
int hashValue3 = hashValue2 + xorValues[i3, 3];
if (rainbowMasks[hashValue3, 3]) continue;
rainbowMasks[hashValue3, 3] = true;
for (int i4 = 0; i4 < length; i4++)
{
int hashValue4 = hashValue3 + xorValues[i4, 4];
if (rainbowMasks[hashValue4, 4]) continue;
rainbowMasks[hashValue4, 4] = true;
for (int i5 = 0; i5 < length; i5++)
{
int hashValue5 = hashValue4 + xorValues[i5, 5];
if (rainbowMasks[hashValue5, 5]) continue;
rainbowMasks[hashValue5, 5] = true;
for (int i6 = 0; i6 < length; i6++)
{
int hashValue6 = hashValue5 + xorValues[i6, 6];
if (rainbowMasks[hashValue6, 6]) continue;
rainbowMasks[hashValue6, 6] = true;
for (int i7 = 0; i7 < length; i7++)
{
int hashValue7 = hashValue6 + xorValues[i7, 7];
if (rainbowMasks[hashValue7, 7]) continue;
rainbowMasks[hashValue7, 7] = true;
for (int i8 = 0; i8 < length; i8++)
{
int hashValue8 = hashValue7 + xorValues[i8, 8];
if (rainbowMasks[hashValue8, 8]) continue;
rainbowMasks[hashValue8, 8] = true;
for (int i9 = 0; i9 < length; i9++)
{
int hashValue9 = hashValue8 + xorValues[i9, 9];
if (rainbowMasks[hashValue9, 9]) continue;
rainbowMasks[hashValue9, 9] = true;
for (int i10 = 0; i10 < length; i10++)
{
int hashValue10 = hashValue9 + xorValues[i10, 10];
if (rainbowMasks[hashValue10, 10]) continue;
rainbowMasks[hashValue10, 10] = true;
for (int i11 = 0; i11 < length; i11++)
{
int hashValue11 = hashValue10 + xorValues[i11, 11];
if (rainbowMasks[hashValue11, 11]) continue;
rainbowMasks[hashValue11, 11] = true;
for (int i12 = 0; i12 < length; i12++)
{
int hashValue12 = hashValue11 + xorValues[i12, 12];
if (rainbowMasks[hashValue12, 12]) continue;
rainbowMasks[hashValue12, 12] = true;
for (int i13 = 0; i13 < length; i13++)
{
int hashValue13 = hashValue12 + xorValues[i13, 13];
if (rainbowMasks[hashValue13, 13]) continue;
rainbowMasks[hashValue13, 13] = true;
for (int i14 = 0; i14 < length; i14++)
{
int hashValue14 = hashValue13 + xorValues[i14, 14];
if (rainbowMasks[hashValue14, 14]) continue;
rainbowMasks[hashValue14, 14] = true;
for (int i15 = 0; i15 < length; i15++)
{
ushort computerHashValue = (ushort)(hashValue14 + xorValues[i15, 15]);
if (rainbowTable[computerHashValue] == null)
{
rainbowTable[computerHashValue] = new string(new char[] { validPasswordChars[i1], validPasswordChars[i2], validPasswordChars[i3], validPasswordChars[i4], validPasswordChars[i5], validPasswordChars[i6], validPasswordChars[i7], validPasswordChars[i8], validPasswordChars[i9], validPasswordChars[i10], validPasswordChars[i11], validPasswordChars[i12], validPasswordChars[i13], validPasswordChars[i14], validPasswordChars[i15] });
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
}
private static ushort GetTailPasswordHash(int tailPasswordLength, ushort[,] xorTailPasswordValues)
{
int tailPasswordHashValue = 0;
for (int i = PasswordMaxLength - tailPasswordLength + 1, j = 0; i <= PasswordMaxLength; i++, j++)
{
tailPasswordHashValue += (xorTailPasswordValues[j, i]);
}
return (ushort)tailPasswordHashValue;
}
#endregion
#endregion
}
附上我写的SourceSafePasswordRecovery工具。
posted on 2009-03-12 17:50 Kevin Shan 阅读(2886) 评论(19) 编辑 收藏 举报