天天看點

ios--聯網通信加密介紹

原文轉自:http://blog.csdn.net/nono_love_lilith/article/details/7696533

通信加解密基本算是每個涉及到使用者資訊的用戶端都會用到的一個技術。

一般我們可能就做簡單的防篡改和密文加密。

很多時候做一個加密隻不過是一個小小的心理安慰吧了,因為純粹的從安全角度來說,安全性真的不高。

對于一些手機支付以及銀聯的用戶端,我看到有用的證書什麼來實作。

因為沒做過,是以也不是太了解。

這邊就說下最簡單的加密方案。

一:MD5數字摘要。

準确來說,MD5不能叫做加解密,因為它不可逆性。

一般我們了解的加解密是能加密,然後解密的。

MD5隻是根據資料生個一個校驗碼,然後對于資料接受者接受到内容後同樣的在通過md5來生成校驗碼于之前的校驗碼對比是否一緻,

進而來判斷資料在傳送過程中是否被截取篡改過。

說白了,其實在傳輸過程中,僅僅md5技術,資料任然是明文的。

下面我來來看下IOS中對md5加密的支援。

[cpp]  view plain copy

  1. const char *original_str = [string UTF8String];//string為摘要内容,轉成char  
  2.    unsigned char result[CC_MD5_DIGEST_LENGTH];    
  3.    CC_MD5(original_str, strlen(original_str), result);//調通系統md5加密  
  4.    NSMutableString *hash = [[NSMutableString string]autorelease];  
  5.    for (int i = 0; i < 16; i++)  
  6.        [hash appendFormat:@"%02X", result[i]];  
  7.       return hash ;//校驗碼  

代碼很簡單,因為内部算法都是系統已經完成的。

對于以上來看,仍然沒有很好的處理密文傳輸隻是在資料傳輸過程成做了一個簡單的防篡改。

是以需要使用一種能生成密文的安全機制類支援。

二:ios中3DES加密

3DES是一種對稱的加密方式,因為用的同一個密鑰。

對于加解密的安全性什麼大家可以google,baidu自己找資料參考。

我也不過是簡單的說一下通信加密中的一種可實作方案而已。

同樣的3DES加密基本也都是統一的,系統也直接提供了API,基本代碼如下

[cpp]  view plain copy

  1. //3des加解密  
  2. + (NSString*)TripleDES:(NSString*)plainText encryptOrDecrypt:(CCOperation)encryptOrDecrypt  
  3. {  
  4.     const void *vplainText;  
  5.     size_t plainTextBufferSize;  
  6.     if (encryptOrDecrypt == kCCDecrypt)//解密  
  7.     {  
  8.         NSData *EncryptData = [GTMBase64 decodeData:[plainText dataUsingEncoding:NSUTF8StringEncoding]];  
  9.         plainTextBufferSize = [EncryptData length];  
  10.         vplainText = [EncryptData bytes];  
  11.     }  
  12.     else //加密  
  13.     {  
  14.         NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];  
  15.         plainTextBufferSize = [data length];  
  16.         vplainText = (const void *)[data bytes];  
  17.     }  
  18.     CCCryptorStatus ccStatus;  
  19.     uint8_t *bufferPtr = NULL;  
  20.     size_t bufferPtrSize = 0;  
  21.     size_t movedBytes = 0;  
  22.     bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);  
  23.     bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));  
  24.     memset((void *)bufferPtr, 0x0, bufferPtrSize);  
  25.     // memset((void *) iv, 0x0, (size_t) sizeof(iv));  
  26.      const void *vkey = (const void *) [DESKEY UTF8String];  
  27.    // NSString *initVec = @"init Vec";  
  28.     //const void *vinitVec = (const void *) [initVec UTF8String];  
  29.    //  Byte iv[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};  
  30.     ccStatus = CCCrypt(encryptOrDecrypt,  
  31.                        kCCAlgorithm3DES,  
  32.                         kCCOptionPKCS7Padding | kCCOptionECBMode,  
  33.                        vkey,   
  34.                        kCCKeySize3DES,  
  35.                        nil,   
  36.                        vplainText,  
  37.                        plainTextBufferSize,  
  38.                        (void *)bufferPtr,  
  39.                        bufferPtrSize,  
  40.                        &movedBytes);  
  41.     //if (ccStatus == kCCSuccess) NSLog(@"SUCCESS");  
  42.     NSString *result;  
  43.     if (encryptOrDecrypt == kCCDecrypt)  
  44.     {  
  45.         result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr   
  46.                                                                 length:(NSUInteger)movedBytes]   
  47.                                         encoding:NSUTF8StringEncoding]   
  48.                   autorelease];  
  49.     }  
  50.     else  
  51.     {  
  52.         NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];  
  53.         result = [GTMBase64 stringByEncodingData:myData];  
  54.     }  
  55.     return result;  

這個在網上也能搜尋到詳細代碼。

但是要注意到一點:

[cpp]  view plain copy

  1. CCCrypt(encryptOrDecrypt,  
  2.                        kCCAlgorithm3DES,  
  3.                         kCCOptionPKCS7Padding | kCCOptionECBMode,  
  4.                        vkey,   
  5.                        kCCKeySize3DES,  
  6.                        nil,   
  7.                        vplainText,  
  8.                        plainTextBufferSize,  
  9.                        (void *)bufferPtr,  
  10.                        bufferPtrSize,  
  11.                        &movedBytes);  

這個裡面的參數可能會根據你服務端使用的對應的3des算法構造時參數的不同而需要自己調整。

比如我在網上看到的這個第三個參數隻是用了kCCOptionPKCS7Padding,第六個可選參數用了上面一個自定義的iv。

但是這邊根據伺服器,這個參數是nil才對應。

這邊也附上java端的加解密代碼

[java]  view plain copy

  1. public String encryptThreeDESECB(String src,String key) throws Exception  
  2.     {  
  3.       DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));  
  4.       SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");  
  5.       SecretKey securekey = keyFactory.generateSecret(dks);  
  6.       Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");  
  7.       cipher.init(Cipher.ENCRYPT_MODE, securekey);  
  8.       byte[] b=cipher.doFinal(src.getBytes());  
  9.       BASE64Encoder encoder = new BASE64Encoder();  
  10.       return encoder.encode(b).replaceAll("\r", "").replaceAll("\n", "");  
  11.     }  
  12.     //3DESECB解密,key必須是長度大于等于 3*8 = 24 位  
  13.     public String decryptThreeDESECB(String src,String key) throws Exception  
  14.     {  
  15.       //--通過base64,将字元串轉成byte數組  
  16.       BASE64Decoder decoder = new BASE64Decoder();  
  17.       byte[] bytesrc = decoder.decodeBuffer(src);  
  18.       //--解密的key  
  19.       DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));  
  20.       SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");  
  21.       SecretKey securekey = keyFactory.generateSecret(dks);  
  22.       //--Chipher對象解密  
  23.       Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");    
  24.       cipher.init(Cipher.DECRYPT_MODE, securekey);    
  25.       byte[] retByte = cipher.doFinal(bytesrc);    
  26.       return new String(retByte);  
  27.     }  

内容也很少,這這麼點。

然後是key,也就是共用密鑰的用戶端和服務端都儲存一個。

簡單從資料傳輸來說,密文傳輸了,安全性相對來說提高了不少。

但是如果破解了用戶端代碼,那麼其實密鑰也就暴露了。

這對于android上面來說,因為反編譯額純在,安全性不敢恭維,

ios的貌似好一點,因為暫未聽說反編譯ios的app的。

以上就是一種簡單的通信加密方案。

當然,其實這些其實算是通用技術~