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