3des(或称为triple des)是三重数据加密算法(tdea,triple data encryption algorithm)块密码的通称。它相当于是对每个数据块应用三次des加密算法。由于计算机运算能力的增强,原版des密码的密钥长度变得容易被暴力破解;3des即是设计用来提供一种相对简单的方法,即通过增加des的密钥长度来避免类似的攻击,而不是设计一种全新的块密码算法。
3des又称triple des,是des加密算法的一种模式,它使用3条56位的密钥对数据进行三次加密。数据加密标准(des)是美国的一种由来已久的加密标准,它使用对称密钥加密法,并于1981年被ansi组织规范为ansi x.3.92。des使用56位密钥和密码块的方法,而在密码块的方法中,文本被分成64位大小的文本块然后再进行加密。比起最初的des,3des更为安全。
一行代码实现3des加密解密需要用到写的 jkencrypt https://github.com/jukai9316/jkencrypt。
下面先解析以下3des的实现,然后再说,如何使用jkencrypt。
注意点:填充方式不一样
在与后台交互的过程中,由于java 里面用的是pkcs5padding,而ios只有kccoptionpkcs7padding,所以用kccoptionpkcs7padding | kccoptionecbmode 相当于pkcs5padding。
以下是3des 256 在ios开发中的实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
#import <commoncrypto/commondigest.h> #import <commoncrypto/commoncryptor.h> #import <security/security.h> #import "gtmbase64.h" //密匙 key #define gkey @"kyle_chu" //偏移量 #define giv @"jukai" //字符串加密 -(nsstring *)doencryptstr:(nsstring *)originalstr{ //把string 转nsdata nsdata* data = [originalstr datausingencoding:nsutf8stringencoding]; //length size_t plaintextbuffersize = [data length]; const void *vplaintext = ( const void *)[data bytes]; cccryptorstatus ccstatus; uint8_t *bufferptr = null; size_t bufferptrsize = 0; size_t movedbytes = 0; bufferptrsize = (plaintextbuffersize + kccblocksize3des) & ~(kccblocksize3des - 1); bufferptr = malloc ( bufferptrsize * sizeof (uint8_t)); memset (( void *)bufferptr, 0x0, bufferptrsize); const void *vkey = ( const void *) [gkey utf8string]; //偏移量 const void *vinitvec = ( const void *) [giv utf8string]; //配置cccrypt ccstatus = cccrypt(kccencrypt, kccalgorithm3des, //3des kccoptionecbmode|kccoptionpkcs7padding, //设置模式 vkey, //key kcckeysize3des, vinitvec, //偏移量,这里不用,设置为nil;不用的话,必须为nil,不可以为@“” vplaintext, plaintextbuffersize, ( void *)bufferptr, bufferptrsize, &movedbytes); nsdata *mydata = [nsdata datawithbytes:( const void *)bufferptr length:(nsuinteger)movedbytes]; nsstring *result = [gtmbase64 stringbyencodingdata:mydata]; return result; } //字符串解密 -(nsstring*)dodecencryptstr:(nsstring *)encryptstr{ nsdata *encryptdata = [gtmbase64 decodedata:[encryptstr datausingencoding:nsutf8stringencoding]]; size_t plaintextbuffersize = [encryptdata length]; const void *vplaintext = [encryptdata bytes]; cccryptorstatus ccstatus; uint8_t *bufferptr = null; size_t bufferptrsize = 0; size_t movedbytes = 0; bufferptrsize = (plaintextbuffersize + kccblocksize3des) & ~(kccblocksize3des - 1); bufferptr = malloc ( bufferptrsize * sizeof (uint8_t)); memset (( void *)bufferptr, 0x0, bufferptrsize); const void *vkey = ( const void *) [gkey utf8string]; const void *vinitvec = ( const void *) [giv utf8string]; ccstatus = cccrypt(kccdecrypt, kccalgorithm3des, kccoptionpkcs7padding|kccoptionecbmode, vkey, kcckeysize3des, vinitvec, vplaintext, plaintextbuffersize, ( void *)bufferptr, bufferptrsize, &movedbytes); nsstring *result = [[nsstring alloc] initwithdata:[nsdata datawithbytes:( const void *)bufferptr length:(nsuinteger)movedbytes] encoding:nsutf8stringencoding]; return result; } |
十六进制的实现省略了,可以阅读jkencrypt.m
jkencrypt的使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
//1、设置您需要的密匙、偏移量 //密匙 key #define gkey @"kyle_chu" //偏移量 #define giv @"jukai" // @"kyle_jukai" 是测试字符串,换成您需要加密的内容即可 jkencrypt * en = [[jkencrypt alloc]init]; //加密 nsstring * encryptstr = [en doencryptstr: @ "kyle_jukai" ]; nsstring * encrypthex = [en doencrypthex: @ "kyle_jukai" ]; nslog(@ "字符串加密:%@" ,encryptstr); nslog(@ "十六进制加密:%@" ,encrypthex); //解密 nsstring *decencryptstr = [en dodecencryptstr:encryptstr]; nsstring *decencrypthex = [en doencrypthex:encrypthex]; nslog(@ "字符串解密:%@" ,decencryptstr); nslog(@ "字符串解密:%@" ,decencrypthex); |
ps:ios des加密与3des加密
最近项目中遇到了加解密的问题,然后翻阅了相关资料,成功搞定。 现在将这些知识点总结一下,一是为了以后复习,二是为了给大家提供参考。
1. 先来说说des操作,定义我这里就不叙述了,网上一堆一堆的。接下来说一下使用时应该注意的几点。 首先,大家要分清key(密钥),data(待操作数据)跟mode(加密模式)。其中key必须为8字节(64位),data需要是8字节(64位)的倍数,这里需要注意了,如果data不是8字节的倍数,那么我们需要进行数据填充,数据填充使用的算法不一定相同。mode貌似有许多种,这里只简单的说一下ecb跟cbc模式。
ecb模式:将待处理的数据分成若干块,每块的长度都为8字节(64位),与key长度相同。然后对每块进行加密或解密,最后将他们连接在一起便是最终的结果。每一块的数据互不干扰。
cbc模式:也需要将待处理的数据分块,但是每一块数据在加密或者解密之前都要与前一块的结果做一次异或操作,因此该模式需要定义一个特殊的8字节key,用于和第一块数据做异或操作。这个特殊的key就是通常说的初始化向量。在代码中书写时需要配置iv参数,注意iv参数是对应cbc模式的。这样一来,每一块数据都是有联系的,这是与ecb模式不同的一点。
2. 再来说说3des操作,也就是进行3次des操作。设ek()和dk()分别代表des算法的加密和解密过程,k代表des算法使用的密钥,p代表明文,c代表密文,则3des算法的过程可表示为:
c = ek3(dk2(ek1(p)))
p = dk1(ek2(dk3(c)))
3des同样有ecb跟cbc模式,同上面讲的一样。这里需要注意一下key的长度,应该是24位。比如我们已知的key是16位的,那么我们需要将其分为2段,每一段都是8位,则k1=左8位, k2=右8位,k3=左8位,也就是 k1=k3,但不能k1=k2=k3,因为如果每段使用的key都相同,就回到des算法了。