DES加密

 

DES加密算法在很多行业都有着非常广泛的应用,对于初学者,开始很容易被ECB、CBC以及计算MAC搞得困惑不已,下面我将一一介绍这几者之间的关系,希望对新人有帮助。为了易于表述,下面所有的密钥及数据都用16进制字符串表示(比如:0x12 0x34 0x56 0x78会被直接写成12345678)。另外,最好你手头上有DES计算工具,以便做一些演算,这样可以更好地学习本篇文章的内容。)

1. DES(单倍长)与3DES(双倍长)ECB加密

        1.1 DES

        SDES_Key=3DES_Key_Left8=9BED98891580C3B2

        Input=F4F3E7B3566F6622  // D1

        ECB加密的结果=5416B1A553743610  // O1

        Input=098750B491EA8D5C  // D2

        ECB加密的结果=48A9014362846BA2  //

        Input=F4F3E7B3566F6622098750B491EA8D5C  // D1 || D2

        ECB加密的结果=5416B1A55374361048A9014362846BA2  // O1 || O2

        每一轮DES ECB加密都是把数据按8字节来分组,各个分组之间彼此独立

        1.2 3DES(双倍长

        3DES_Key=9BED98891580C3B245FE9EC58BFA8D2A  // 左边8字节的Key和SDES_Key一样

        Input=F4F3E7B3566F6622098750B491EA8D5C

        ECB加密的结果=FE7B6C8A73167964798EBAC2BA4899AA

        看过PBOC规范中关于3DES ECB加密的描述,3DES和DES加密的差别在于3DES加密是在DES加密的结果基础上再用右边8字节的密钥解密,

        然后再用左边8字节的密钥进行加密,得到的结果即最终密文数据。演算过程如下

        3DES_Key_Left8=9BED98891580C3B2

        3DES_Key_Right8=45FE9EC58BFA8D2A

        (1)用3DES_Key_Left8(9BED98891580C3B2)对Input(F4F3E7B3566F6622098750B491EA8D5C)加密得到5416B1A55374361048A9014362846BA2;

        (2)用3DES_Key_Right8(45FE9EC58BFA8D2A)对5416B1A55374361048A9014362846BA2解密得到685F98099C7D741B9A849E2C8DFFC430

        (3)3DES_Key_Left8(9BED98891580C3B2)对685F98099C7D741B9A849E2C8DFFC430加密得到FE7B6C8A73167964798EBAC2BA4899AA。

         是不是很简单?

2. ECB加密模式和CBC加密模式的差异

        3DES_Key=9BED98891580C3B245FE9EC58BFA8D2A

        IV=0000000000000000  // 初始向量,其作用是先与Input的前8字节做异或运算,得到的结果才被用于DES加密

        Input=F4F3E7B3566F6622098750B491EA8D5C

        ECB加密的结果=FE7B6C8A73167964798EBAC2BA4899AA

        CBC加密的结果=FE7B6C8A731679649273F6368EAE9E98

        ECB加密和CBC加密的结果是不是有点像?这里2者的结果差异是前8字节一样,后面的不一样,为什么?

        因为对于CBC加密来说,其加密是链式的,后面的加密结果依赖于前面的结果

        对于第一块待加密数据,其首先要和IV异或得到D1,D1作为真实的输入,对D1加密得到的结果记为O1;

        对于第二块待加密数据,其首先要和O1异或得到D2,D2作为真实的输入,对D2加密得到的结果记为O2。

        如果还有其他数据,类推,直到算出最终的结果。

        我们来演算一下CBC的加密过程:

        (1)IV(0000000000000000)和Input的第一块数据F4F3E7B3566F6622进行异或运算得到F4F3E7B3566F6622(因为IV是全0的缘故,第一块输入数据并没有改变!),记为D1。

        (2)对D1进行ECB加密得到FE7B6C8A73167964,记为O1。

        (3)O1和第二块输入数据进行异或运算得到F7FC3C3EE2FCF438,记为D2。

        (4)对D2进行ECB加密得到9273F6368EAE9E98,

        最终的CBC加密结果O1||O2,FE7B6C8A731679649273F6368EAE9E98。

        所以从本质上讲,ECB、CBC只是在对输入数据的处理上有差异,对于底层的加密算法,实际上都是ECB加密模式。

3. MAC的真实面目

        3.1 单倍长密钥计算MAC

        对于单倍长密钥计算MAC,通常都是采用ANSI X9.9标准,其本质就是CBC加密,取最终的结果的最后8字节为MAC(有些规范再取其中的前4字节为MAC)。

        SDES_Key=9BED98891580C3B2

        IV=0000000000000000  // 初始向量,CBC加密运算需要

        Input=F4F3E7B3566F6622098750B491EA8D5C6

        CBC加密结果=5416B1A5537436105B6E2CAC0F87986F

        取最后的8字节为MAC即:5B6E2CAC0F87986F

        3.2 双倍长密钥计算MAC

        PBOC规范中采用的双倍长MAC计算方法(与ISO 9797-1 MAC algorithm3 一致)是:

        (1)用左边8字节的密钥对输入数据进行CBC加密,取密文的最后8字节,记为O1

        (2)用右边8字节的密钥对O1进行ECB解密得到O2

        (3)用左边8字节的密钥对O2进行ECB加密得到O3,O3即最终 MAC。

        3DES_Key=9BED98891580C3B245FE9EC58BFA8D2A

        IV=0000000000000000  // 初始向量,CBC加密运算需要

        Input=F4F3E7B3566F6622098750B491EA8D5C$ K+ [6 z2 x3 c$ O

        (1)用3DES_Key_Left8(9BED98891580C3B2)对Input(F4F3E7B3566F6622098750B491EA8D5C)CBC加密得到5416B1A5537436105B6E2CAC0F87986F,

                 去最后8字节5B6E2CAC0F87986F为O1;

        (2)用3DES_Key_Right8(45FE9EC58BFA8D2A)对O1(5B6E2CAC0F87986F)ECB解密得到0C583C96DE7074B4,记为O2;

        (3)3DES_Key_Left8(9BED98891580C3B2)对O2(0C583C96DE7074B4)ECB加密得到MAC(95FA419313B62BA4)

4. DES算法的校验位

       DES算法每组密钥为8字节,64bits,实际上参与加/解密运算的只有56bits,因为密钥的每个字节的最低bit(bit 1)被设计成奇偶校验位,所以实际上你用密钥9AEC99881481C2B3替换本文上面的9BED98891580C3B2,这两个密钥的差异只是每个字节的最低bit不一样,但是你会发现所有的计算结果都是一样的。

         结语,MAC算法本质上就是CBC加密算法,对于3DES MAC计算还需加上一点变化,而CBC加密本质上还是ECB加密。

 

   以上是转自网友的比较好的一篇关于DES加密不同的加密模式特点(转载自 https://m.oschina.net/blog/271363) 下面是对于iOS的 DES 加密代码

     

 1 #define ENCRYKEY @"1234567890123456"
 2 
 3  
 4 
 5 @implementation NSString (Encry)
 6 
 7  
 8 
 9 //加密
10 
11 + (NSString *)desEnctyWithStr:(NSString *)str
12 
13 {
14 
15     const char *vStr = [str UTF8String];
16 
17     NSUInteger dataLength = [str length];
18 
19     const void *vKey = [ENCRYKEY UTF8String];
20 
21     
22 
23     unsigned char buffer[1024];
24 
25     memset(buffer, 0, sizeof(char));
26 
27     size_t numBytesEncty = 0;
28 
29     const void *iv = [@"00000000" UTF8String]; //对于CBC模式的DES加密需要添加初始化向量
30 
31     CCCryptorStatus crytorStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES, kCCOptionPKCS7Padding, vKey, kCCKeySizeDES, iv,vStr, dataLength, buffer, 1024, &numBytesEncty);
32 
33     //加密函数 (加密模式(加密/解密),加密方式(DES,3DES,md5等),加密数据的填充方式(DES为64位加密,如果不够的填充方式),加密key,key的长度,加密初始化向量(对于CBC模式需要添加),加密字符串,加密字符串长度,结果字符串,结果输出的缓冲区大小,结果长度)
34 
35     
36 
37     NSString *plainText = nil;
38 
39     if (crytorStatus == kCCSuccess) {
40 
41         NSData *data = [NSData dataWithBytes:buffer length:numBytesEncty];
42 
43         plainText = [[NSString alloc]initWithData:[GTMBase64 encodeData:data] encoding:NSUTF8StringEncoding];
44 
45     }
46 
47     return plainText;
48 
49 }
50 
51  
52 
53 //解密
54 
55 + (NSString *)strWithDesEncty:(NSString *)desStr
56 
57 {
58 
59     const void *vKey = [ENCRYKEY UTF8String];
60 
61  
62 
63     NSData *data = [GTMBase64 decodeString:desStr];
64 
65     unsigned char buffer[1024];
66 
67     memset(buffer, 0, sizeof(char));
68 
69     size_t numBytesEncty = 0;
70 
71     const void *iv = [@"00000000" UTF8String]; //对于CBC模式的DES加密需要添加初始化向量
72 
73  
74 
75     CCCryptorStatus crytorStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES, kCCOptionPKCS7Padding, vKey, kCCKeySizeDES, iv,[data bytes], [data length], buffer, 1024, &numBytesEncty);
76 
77     
78 
79     NSString *plainText = nil;
80 
81     if (crytorStatus == kCCSuccess) {
82 
83         NSData *data = [NSData dataWithBytes:buffer length:numBytesEncty];
84 
85         plainText = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
86 
87     }
88 
89     return plainText;
90 
91 }

 

 但是当前的代码加密出来的 数据 与网页上在线加密的结果不一样,这一点还在看是为什么?

posted @ 2015-10-14 11:07  风吹花落  阅读(458)  评论(0)    收藏  举报