在NTLM中使用DES算法生成LM-HASH和NTLM-HASH(以后在介绍)。我们现讨论DES算法的实现。 DES是Data Encryption Standard(数据加密标准)的缩写。它是由IBM公司研制的一种加密算法,美国国家标准局于1977年公布把它作为非机要部门使用的数据加密标准,二十年来,它一直活跃在国际保密通信的舞台上,扮演了十分重要的角色。而DES算法本身称自己为DEA(Data Encryption Althorithm),因此DES和DEA实际是同一个东东。
DES输入64bit的数据源,通过56bits的key(由8bytes去掉CRC校验位获得,输入也可以看作是64bits,至少在程序代码中是这样体现),生成一个64bits的结果,DES属于对称加密方式。一共分为三个步骤。
在实现的过程中,最为郁闷的是网上有很多代码和例子,也有一些检测工具,例如Crytotool1.2,但是很奇怪,他们给出的结果不一样,因此有必要认真了解一下整个DES的过程。
步骤一:源和key的初始化序列改动(Initail permutation)
通过对比特的序列移动,生成新的源’和key’,用于后续的算法计算。
A:对源的处理
8字节,共64bits,从1到64按下面左阵列的摆列方式,经过序列移动,成规下面右阵列的排列方式,实际上新的第一个8bit就是左阵列的第2 列,从下到上的顺序,后面的7组8比特分别为第4、6、8、1、3、5、7列从下到上的排序。这种方式,我想对于芯片实现是很便利的,可惜C编程语言不等 直接按列处理,只好写段代码来实现。
| 1 2 3 4 5 6 7 8| |58 50 42 34 26 18 10 2|
| 9 10 11 12 13 14 15 16| |60 52 44 36 28 20 12 4|
|17 18 19 20 21 22 23 24| |62 54 46 38 30 22 14 6|
|25 26 27 28 29 30 31 32| |64 56 48 40 32 24 16 8|
|33 34 35 36 37 38 39 40| -> |57 49 41 33 25 17 9 1|
|41 42 43 44 45 46 47 48| |59 51 43 35 27 19 11 3|
|49 50 51 52 53 54 55 56| |61 53 45 37 29 21 13 5|
|57 58 59 60 61 62 63 64| |63 55 47 39 31 23 15 7|
实现代码:
//变换序列
static int ip_data_seq[] = {
58,50,42,34,26,18,10,2,
60,52,44,36,28,20,12,4,
62,54,46,38,30,22,14,6,
64,56,48,40,32,24,16,8,
57,49,41,33,25,17,9,1 ,
59,51,43,35,27,19,11,3,
61,53,45,37,29,21,13,5,
63,55,47,39,31,23,15,7};
//由于后面存在大量的比特操作,而C程序中一般以字节为单位,因此我们将字节中的比特分别
//存贮在8个字节中,以方便后面的大量运算
static void storebit(IN unsigned char * data, IN int data_len, OUT unsigned char * dst){
int i = 0;
for(i = 0 ; i
B:对key的处理
对于输入的8字节的key,每个字节去除其CRC校验位(第8位),然后经过类似的序列移位生成了56bit的新的key。从这个处理,我们也可以看出DES算法的古老,采用流的概念,而CRC校验位用于初期比较古老的误码率高的通信中。
这种以通信以流的方式传递,需要注意和我们程序中的顺序问题。如果我们使用byte(unsinged char)来放置一8bit的信息,那么第一位是我们byte的高位。这与我们网络编程中碰到的little_endian和big_endian的情况有点类似。闲话少谈,移动位的方式如下:
| 1 2 3 4 5 6 7 8 | |57 49 41 33 25 17 9| |57 49 41 33 25 17 9 1|
| 9 10 11 12 13 14 15 16| | 1 58 50 42 34 26 18| |58 50 42 34 26 18 10 2|
|17 18 19 20 21 22 23 24| |10 2 59 51 43 35 27| |59 51 43 35 27 19 11 3|
|25 26 27 28 29 30 31 32| |19 11 3 60 52 44 36| |60 52 44 36 |
|33 34 35 36 37 38 39 40| -> |63 55 47 39 31 23 15| -> |63 55 47 39 31 23 15 7|
|41 42 43 44 45 46 47 48| | 7 62 54 46 38 30 22| |62 54 46 38 30 22 14 6|
|49 50 51 52 53 54 55 56| |14 6 61 53 45 37 29| |61 53 45 37 29 21 13 5|
|57 58 58 60 61 62 63 64| |21 13 5 28 20 12 4| |28 20 12 4 |
中间和右图是一样的,只是我们采用7bit一组还是按照8bit一组的方式存放,我们希望通过右图给出一个有规律的处理。
static int ip_key_seq[] ={
57,49,41,33,25,17,9,
1,58,50,42,34,26,18,
10,2,59,51,43,35,27,
19,11,3,60,52,44,36,
63,55,47,39,31,23,15,
7,62,54,46,38,30,22,
14,6,61,53,45,37,29,
21,13,5,28,20,12,4};
//算法主函数
void algorithm_des(IN unsigned char * src, IN unsigned char * secrect,
OUT unsigned char * dst){
unsigned char s[64],key[64],L[32],R[32],K[48],E[48];
int i = 0;
//步骤1
storebit(src,8,s);
storebit(secrect,8,key);
initail_permutation(s,ip_data_seq,64,s);
initail_permutation(key,ip_key_seq,56,key);
}
OK,终于完成了第一步,得到了s[64]和key[56]为第二步算法的输入。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.e1idc.net