步骤一:转换为大写
将需要加密的明文中所有的小写改为大写,即WELCOME。
步骤二:定长14字节
如果明文得长度超过14字节,将截取前面14字节的数据,如果不足14字节,则以0x00来补齐,即得到二进制:5745 4C43 4F4D 4500 0000 0000 0000
步骤三:分为2组7字节的数据
将14字节均分为两组,即:
组一:57 45 4C 43 4F 4D 45
组二:00 00 00 00 00 00 00
步骤四:分别将2个7字节的数据,各生成64比特的DES的key。
组一:56 A2 52 88 34 7A 34 8A
组二:00 00 00 00 00 00 00 00
步骤五:以步骤四得到的作为DES的key,以“
KGS!@#$%
”作为DES的明文,进行DES加密,分别得到两组64比特的数据。
组一:C2 34 13 A8 A1 E7 66 5F
组二:AA D3 B4 35 B5 14 04 EE
步骤六:将两组64比特的数据连结为16字节的数据,这就是LM Hash的最后的值。
LM-HASH=C23413A8A1E7665FAAD3B435B51404EE
KGS!@#$%的二进制表示
static unsigned char lm_magic[] = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
//from The Samba Team's source/libsmb/smbdes.c,用于步骤四的实现
static void str_to_key ( IN const unsigned char *str, OUT unsigned char *key )
{
unsigned int i;
key[0] = str[0] >> 1;
key[1] = ( ( str[0] & 0x01 ) << 6 ) | ( str[1] >> 2 );
key[2] = ( ( str[1] & 0x03 ) << 5 ) | ( str[2] >> 3 );
key[3] = ( ( str[2] & 0x07 ) << 4 ) | ( str[3] >> 4 );
key[4] = ( ( str[3] & 0x0F ) << 3 ) | ( str[4] >> 5 );
key[5] = ( ( str[4] & 0x1F ) << 2 ) | ( str[5] >> 6 );
key[6] = ( ( str[5] & 0x3F ) << 1 ) | ( str[6] >> 7 );
key[7] = str[6] & 0x7F;
for ( i = 0; i < 8; i++ )
{
key[i] = ( key[i] << 1 );
}
return;
}
//获取16字节的lm-hash内容
void lm_hash(IN char * src, OUT unsigned char * dst, OUT int * dst_len){
int i = 0;
unsigned char lm_src[14];
//步骤一和步骤二
if(strlen(src) >= 14){
memcpy(lm_src,src,14);
}else{
memset(lm_src,0,14);
memcpy(lm_src,src,strlen(src));
}
for(i = 0 ;i < 14; i ++){
lm_src[i] = chrtoupper(lm_src[i]);
}
//步骤三和步骤四
str_to_key(lm_src,dst);
str_to_key(lm_src + 7, dst + 8);
//步骤五和步骤六
algorithm_des(lm_magic, dst,dst);
algorithm_des(lm_magic, dst + 8,dst + 8);
if(dst_len != NULL)
* dst_len = 16;
}//LM-HASH end