天天看點

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