实现PROXY穿越(6):LM-Hash的实现

   最近忙,事比较多,活多了,还要降薪,唉。没什么时间看书,将以前的一些技术blog也移到这里。NTLM在去年年底和今年年初研究过一阵子,写了总结和例子程序。里面涉及很多算法,在网上查了很久。(下面是以前的博客)最近想实现一个通过PROXY穿越的网络编程,将相关的内容进行一下汇总。很多东西来自网络共产主义,也应该为共产主义有所回馈。介绍LM-Hash的实现。

    经过了对DES的努力,终于可以实现LM-HASH,不管离开NTLM还有多远,至少前进了一步。现从网上共产主义来点HASH科普『参 考:http://tech.ddvip.com/2008-12/122818571796653.htm』,然后再介绍LM-HASH的实现。

  Hash,一般翻译为“散列”,也有直接音译为“哈希”的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长 度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来 唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。HASH主要用于信息安全领域中加密算法,它把一些不同长度的 信息转化成杂乱的128位的编码里,叫做HASH值。也可以说,Hash就是找到一种数据内容和数据存放地址之间的映射关系。Hash算法在信息安全方面 的应用主要体现在以下的3个方面:
  (1) 文件校验:
  我们比较熟悉的校验算法有 奇偶校验和CRC校验,这2种校验并没有抗数据篡改的能力,它们一定程度上能检测并纠正数据传输中的信道误码,但却不能防止对数据的恶意破坏。 MD5 Hash算法的“数字指纹”特性,使它成为目前应用最广泛的一种文件完整性校验和(Checksum)算法,不少Unix系统有提供计算md5 checksum的命令。
  (2)数字签名
  Hash 算法也是现代密码体系中的一个重要组成部分。由于非对称算法的运算速度较慢,所以在数字签名协议中,单向散列函数扮演了一个重要的角色。对Hash值,又 称“数字摘要”进行数字签名,在统计上可以认为与对文件本身进行数字签名是等效的。而且这样的协议还有其他的优点。
  (3)鉴权协议
  鉴权协议又被称作挑战--认证模式:在传输信道是可被侦听,但不可被篡改的情况下,这是一种简单而安全的方法。

 
   言归正传,LM HASH是在DES上面实现的,因此它的安全性也如DES的安全性一样收到置疑。LM-HASH的实现分为6个步骤,在我们解决DES算法的基础上,很容易实现。在下面我们以Welcome为例子进行描述:

步骤一:转换为大写
  将需要加密的明文中所有的小写改为大写,即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
检验例子二:Administrator的LM-HASH = 6a 98 eb 0f b8 8a 44 9c be 6f ab fd 82 5b ca 61

相关链接:我的网络通信相关文章

NTLM的实现:

  • 实现PROXY穿越(16):NTLM的PROXY穿越
  • 实现PROXY穿越(15):NTLM Session Security
  • 实现PROXY穿越(14):NTLM type3 Message
  • 实现PROXY穿越(13):NTLM type2 Message
  • 实现PROXY穿越(12):NTLM type1 Message
  • 实现PROXY穿越(11):NTLMv2 session response
  • 实现PROXY穿越(10):NTLMv2 response
  • 实现PROXY穿越(9):NTLMv1 response
  • 实现PROXY穿越(8):NT-Hash的实现
  • 实现PROXY穿越(7):MD4和MD5
  • 实现PROXY穿越(6):LM-Hash的实现
  • 实现PROXY穿越(5):DES算法之三
  • 实现PROXY穿越(4):DES算法之二
  • 实现PROXY穿越(3):DES算法之一
  • 实现PROXY穿越(2):Base64算法
  • 实现PROXY穿越(1):流程和NTLM算法

你可能感兴趣的:(Algorithm,算法,加密,session,Security,DST)