⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ntlmlib.cpp

📁 Windows的NTLM认证方式的加密和解密库(含例子程序)。
💻 CPP
字号:
#include<windows.h>
#include<stdlib.h>
#include<stdio.h>
#include"NTLMLib.h"
#include"d3des.h"
#include"md4.h"

static CODE MagicPlain={0x4B,0x47,0x53,0x21,0x40,0x23,0x24,0x25};

//将7字节的明文lpSrc转换成8字节的散列密文;
BOOL StringToKey(LPCSTR lpSrc,LPSTR lpKey)
{
	BOOL T=FALSE;
	int i;
	if(lpSrc&&lpKey)
	{
		for(i=0;i<8;i++)
		{
			switch(i)
			{
			case 0:
				lpKey[i]=(BYTE)lpSrc[i]&0xfe;
				break;
			case 7:
				lpKey[i]=((BYTE)lpSrc[i-1]&0x7f)<<1;
				break;
			default:
				lpKey[i]=(((BYTE)lpSrc[i]>>(i+1))|(((BYTE)lpSrc[i-1]&((1<<(i+1))-1))<<(7-i)))<<1;
			}
		}
		T=TRUE;
	}
	return T;
}

//转换lpStr字符串中的内容到LMHASH结构中去;
BOOL StringToLMHash(LPLMHASH lpHash,LPCSTR lpStr)
{
	BOOL T=FALSE;
	int len,i;
	BYTE data[14];
	if(lpStr&&lpHash)
	{
		len=strlen(lpStr);
		if(len>=0&&len<15)
		{
			for(i=0;i<len;i++)
			{
				if(lpStr[i]>='a'&&lpStr[i]<='z')
				{
					data[i]=(BYTE)(lpStr[i]-'a'+'A');
				}
				else
				{
					data[i]=(BYTE)lpStr[i];
				}
			}
			if(i<14)
			{
				ZeroMemory(data+i,14-i);
			}
			StringToKey((LPSTR)data,(LPSTR)lpHash->code[0]);
			StringToKey((LPSTR)(data+7),(LPSTR)lpHash->code[1]);
			for(i=0;i<2;i++)
			{
				deskey(lpHash->code[i],EN0);
				des(MagicPlain,lpHash->code[i]);
			}
			T=TRUE;
		}
	}
	return T;
}

//将长度是len的原文lpSrc用MD4算法加密成16字节的密文ret返回;
void md4(MD4 ret,LPCBYTE lpSrc,int len)
{
	MD4_CTX context;
	if(ret&&len>=0)
	{
		MD4Init(&context);
		MD4Update(&context,(unsigned char *)lpSrc,len);
		MD4Final(ret,&context);
	}
}

//转换lpStr字符串中的内容到NTLMHASH结构中去;
BOOL StringToNTLMHash(LPNTLMHASH lpHash,LPCSTR lpStr)
{
	BOOL T=FALSE;
	LPBYTE lpData;
	int len;
	if(lpHash)
	{
		len=lpStr?strlen(lpStr):0;
		if(len>0)
		{
			lpData=new BYTE[len<<1];
			if(lpData)
			{
				mbstowcs((wchar_t *)lpData,lpStr,len);
				md4(lpHash->code,lpData,len<<1);
				delete[] lpData;
				T=TRUE;
			}
		}
		else
		{
			md4(lpHash->code,NULL,0);
			T=TRUE;
		}
	}
	return T;
}

//对密码szPwd用服务器给定的钥匙challenge得到回应串ret;AuthMode是验证类型,可以是NTLMAuth或LMAuth;
BOOL LMAuthen(RESPONSE ret,LPCSTR szPwd,CODE challenge,AuthMode mode)
{
	BOOL T=FALSE;
	int i,j;
	BYTE key[21];
	BYTE data[8];
	if(ret&&szPwd&&challenge)
	{
		ZeroMemory(key,sizeof(key));
		switch(mode)
		{
		case LMAuth:
			{
				LMHASH hash;
				if(StringToLMHash(&hash,szPwd))
				{
					memcpy(key,hash.code[0],sizeof(hash));
					T=TRUE;
				}
			}
			break;
		case NTLMAuth:
			{
				NTLMHASH hash;
				if(StringToNTLMHash(&hash,szPwd))
				{
					memcpy(key,hash.code,sizeof(hash));
					T=TRUE;
				}
			}
			break;
		}
		if(T)
		{
			for(i=0,j=0;i<21;i+=7,j+=8)
			{
				StringToKey((char *)key+i,(char *)data);
				deskey((unsigned char *)data,EN0);
				des((unsigned char *)challenge,(unsigned char *)(ret+j));
			}
		}
	}
	return T;
}

//将16进制数据lpCode按可见方式输出到szHex缓冲中,形成可输出字符串;
void CodeToHex(LPSTR szHex,LPCBYTE lpCode,int len)
{
	int n,i;
	if(szHex&&lpCode&&len>0)
	{
		n=len*2;
		for(i=0;i<len;i++)
		{
			sprintf(szHex,"%02X",lpCode[i]);
			szHex+=2;
		}
	}
}

//将可见的16进制字符串转换成数据形式,len是lpCode的最大缓冲长度,返回实际转换的字节数;
int HexToCode(LPBYTE lpCode,int len,LPCSTR szHex)
{
	int n=0;
	int slen;
	char * stopped;
	char buf[3];
	if(szHex&&lpCode&&len>0)
	{
		slen=strlen(szHex)&~1;
		if(slen>0)
		{
			buf[2]=0;
			do
			{
				buf[0]=szHex[0];
				buf[1]=szHex[1];
				szHex+=2;
				lpCode[n]=(BYTE)strtoul(buf,&stopped,16);
				if(!stopped||stopped-buf<2)
				{
					break;
				}
				n++;
				slen-=2;
			}
			while(n<len&&slen>0);
		}
	}
	return n;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -