天天看点

IOS中DES与MD5加密方案

md5算法和des算法是常见的两种加密算法。

md5:md5是一种不可逆的加密算法,按我的理解,所谓不可逆,就是不能解密,那么它有什么用的,它的用处大了,大多数的登录功能都会使用到这种算法。后面根据我的项目经验来介绍。

des:一种使用密钥加密的块算法,所以,使用它加密时,需要一个密钥,加上一些设置和你需要加密的文段。

在ios中,使用这两种加密算法非常简单,系统的<commoncrypto/commoncrypto.h>库给我们提供的边界的接口。在很多移动项目中,安卓平台和ios平台的后台服务是统一的,比如一个登录功能是这样的流程:

1、客户端向服务端请求密钥,请求的参数是双方约定好的一个md5加密的字符串。我们可以通过下面的进行第一步加密:

<a href="http://my.oschina.net/u/2340880/blog/395802#">?</a>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

<code>- (nsstring *)md5digest</code>

<code>{</code>

<code>    </code><code>//要进行utf8的转码</code>

<code>    </code><code>const</code> <code>char</code><code>* input = [self utf8string];</code>

<code>    </code><code>unsigned </code><code>char</code> <code>result[cc_md5_digest_length];</code>

<code>    </code><code>cc_md5(input, (cc_long)</code><code>strlen</code><code>(input), result);</code>

<code>    </code> 

<code>    </code><code>nsmutablestring *digest = [nsmutablestring stringwithcapacity:cc_md5_digest_length * 2];</code>

<code>    </code><code>for</code> <code>(nsinteger i = 0; i &lt; cc_md5_digest_length; i++) {</code>

<code>        </code><code>[digest appendformat:@</code><code>"%02x"</code><code>, result[i]];</code>

<code>    </code><code>}</code>

<code>    </code><code>return</code> <code>digest;</code>

<code>}</code>

通过这样的方法,我们可以很容易的得到一串md5加密字符串,但是一定要和后台约定好,md5加密的位数是16位还是32位,用上述方法加密出来的时32位,当然他们之间是有联系的,通过下面的方法可以将其转成16为:

<code>+(nsstring *)trransfrommd532tomd516:(nsstring *)md532{</code>

<code>    </code><code>nsstring  * string;</code>

<code>    </code><code>for</code> <code>(</code><code>int</code> <code>i=0; i&lt;24; i++) {</code>

<code>        </code><code>string=[md532 substringwithrange:nsmakerange(8, 16)];</code>

<code>    </code><code>return</code> <code>string;</code>

还有一点需要注意,加密后的大小写也要对应。

2、服务端将得到的md5串和以约定好的md5串进行对比,如果一致,可以放行,返回密钥。

3、客户端取到密钥,将密钥再进行一次md5加密,然后通过des将要传送的数据加密发给服务器。

这一步至关重要,我们先看des的加密代码

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

<code>+(nsstring *) encryptusedes:(nsstring *)cleartext key:(nsstring *)key andiv:(nsstring *)iv</code>

<code>    </code><code>//这个iv 是des加密的初始化向量,可以用和密钥一样的md5字符</code>

<code>    </code><code>nsdata * date = [iv datausingencoding:nsutf8stringencoding];</code>

<code>    </code><code>nsstring *ciphertext = nil;</code>

<code>    </code><code>nsuinteger datalength = [cleartext length];</code>

<code>    </code><code>nsdata *textdata = [cleartext datausingencoding:nsutf8stringencoding];</code>

<code>    </code><code>unsigned </code><code>char</code> <code>buffer[1024];</code>

<code>    </code><code>memset</code><code>(buffer, 0, </code><code>sizeof</code><code>(</code><code>char</code><code>));</code>

<code>    </code><code>size_t</code> <code>numbytesencrypted = 0;</code>

<code>    </code><code>cccryptorstatus cryptstatus = cccrypt(kccencrypt,</code><code>//加密模式 kccdecrypt 代表解密</code>

<code>                                          </code><code>kccalgorithmdes,</code><code>//加密方式</code>

<code>                                          </code><code>kccoptionpkcs7padding,</code><code>//填充算法</code>

<code>                                          </code><code>[key utf8string], </code><code>//密钥字符串</code>

<code>                                          </code><code>kcckeysizedes,</code><code>//加密位数</code>

<code>                                          </code><code>[date bytes],</code><code>//初始化向量</code>

<code>                                          </code><code>[textdata bytes]  ,</code>

<code>                                           </code><code>datalength,</code>

<code>                                          </code><code>buffer, 1024,</code>

<code>                                          </code><code>&amp;numbytesencrypted);</code>

<code>    </code><code>if</code> <code>(cryptstatus == kccsuccess) {</code>

<code>        </code><code>nslog(@</code><code>"des加密成功"</code><code>);</code>

<code>        </code><code>nsdata *data = [nsdata datawithbytes:buffer length:(nsuinteger)numbytesencrypted];</code>

<code>        </code><code>byte* bb = (byte*)[data bytes];</code>

<code>        </code><code>ciphertext = [base64 parsebytearray2hexstring:bb];</code>

<code>    </code><code>}</code><code>else</code><code>{</code>

<code>        </code><code>nslog(@</code><code>"des加密失败"</code><code>);</code>

<code>    </code><code>return</code> <code>ciphertext;</code>

几点注意:

(1)加密方式,ios官方提供的是如下几种

<code>enum</code> <code>{</code>

<code>    </code><code>kccalgorithmaes128 = 0,</code>

<code>    </code><code>kccalgorithmaes = 0,</code>

<code>    </code><code>kccalgorithmdes,</code>

<code>    </code><code>kccalgorithm3des,       </code>

<code>    </code><code>kccalgorithmcast,       </code>

<code>    </code><code>kccalgorithmrc4,</code>

<code>    </code><code>kccalgorithmrc2,   </code>

<code>    </code><code>kccalgorithmblowfish    </code>

<code>};</code>

(2)填充算法

<code>    </code><code>/* options for block ciphers */</code>

<code>    </code><code>kccoptionpkcs7padding   = 0x0001,</code>

<code>    </code><code>kccoptionecbmode        = 0x0002</code>

<code>    </code><code>/* stream ciphers currently have no options */</code>

我们可以发现,官方提供的只有这两种,然而java使用的却是

<code>kccoptionpkcs7padding</code>

但是不用担心,在密钥是8位的时候,这两种填充算法加密出来的结果试一模一样的。

4、服务器通过相同的方式,解密出密文,通配安卓端。