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 < 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<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>&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、服务器通过相同的方式,解密出密文,通配安卓端。