原文地址http://blog.csdn.net/nono_love_lilith/article/details/7696533
通信加解密基本算是每個涉及到用戶信息的客戶端都會用到的一個技術。
一般我們可能就做簡單的防篡改和密文加密。
很多時候做一個加密只不過是一個小小的心理安慰吧了,因為純粹的從安全角度來說,安全性真的不高。
對於一些手機支付以及銀聯的客戶端,我看到有用的證書什么來實現。
因為沒做過,所以也不是太了解。
這邊就說下最簡單的加密方案。
一:MD5數字摘要。
准確來說,MD5不能叫做加解密,因為它不可逆性。
一般我們理解的加解密是能加密,然后解密的。
MD5只是根據數據生個一個校驗碼,然后對於數據接受者接受到內容后同樣的在通過md5來生成校驗碼於之前的校驗碼對比是否一致,
從而來判斷數據在傳送過程中是否被截取篡改過。
說白了,其實在傳輸過程中,僅僅md5技術,數據任然是明文的。
下面我來來看下IOS中對md5加密的支持。
- const char *original_str = [string UTF8String];//string為摘要內容,轉成char
- /****系統api~~~~*****/
- unsigned char result[CC_MD5_DIGEST_LENGTH];
- CC_MD5(original_str, strlen(original_str), result);//調通系統md5加密
- NSMutableString *hash = [[NSMutableString string]autorelease];
- for (int i = 0; i < 16; i++)
- [hash appendFormat:@"%02X", result[i]];
- return hash ;//校驗碼
代碼很簡單,因為內部算法都是系統已經完成的。
對於以上來看,仍然沒有很好的處理密文傳輸只是在數據傳輸過程成做了一個簡單的防篡改。
因此需要使用一種能生成密文的安全機制類支持。
二:ios中3DES加密
3DES是一種對稱的加密方式,因為用的同一個密鑰。
對於加解密的安全性什么大家可以google,baidu自己找資料參考。
我也不過是簡單的說一下通信加密中的一種可實現方案而已。
同樣的3DES加密基本也都是統一的,系統也直接提供了API,基本代碼如下
- //3des加解密
- + (NSString*)TripleDES:(NSString*)plainText encryptOrDecrypt:(CCOperation)encryptOrDecrypt
- {
- const void *vplainText;
- size_t plainTextBufferSize;
- if (encryptOrDecrypt == kCCDecrypt)//解密
- {
- NSData *EncryptData = [GTMBase64 decodeData:[plainText dataUsingEncoding:NSUTF8StringEncoding]];
- plainTextBufferSize = [EncryptData length];
- vplainText = [EncryptData bytes];
- }
- else //加密
- {
- NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
- plainTextBufferSize = [data length];
- vplainText = (const void *)[data bytes];
- }
- CCCryptorStatus ccStatus;
- uint8_t *bufferPtr = NULL;
- size_t bufferPtrSize = 0;
- size_t movedBytes = 0;
- bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
- bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
- memset((void *)bufferPtr, 0x0, bufferPtrSize);
- // memset((void *) iv, 0x0, (size_t) sizeof(iv));
- const void *vkey = (const void *) [DESKEY UTF8String];
- // NSString *initVec = @"init Vec";
- //const void *vinitVec = (const void *) [initVec UTF8String];
- // Byte iv[] = {0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF};
- ccStatus = CCCrypt(encryptOrDecrypt,
- kCCAlgorithm3DES,
- kCCOptionPKCS7Padding | kCCOptionECBMode,
- vkey,
- kCCKeySize3DES,
- nil,
- vplainText,
- plainTextBufferSize,
- (void *)bufferPtr,
- bufferPtrSize,
- &movedBytes);
- //if (ccStatus == kCCSuccess) NSLog(@"SUCCESS");
- /*else if (ccStatus == kCC ParamError) return @"PARAM ERROR";
- else if (ccStatus == kCCBufferTooSmall) return @"BUFFER TOO SMALL";
- else if (ccStatus == kCCMemoryFailure) return @"MEMORY FAILURE";
- else if (ccStatus == kCCAlignmentError) return @"ALIGNMENT";
- else if (ccStatus == kCCDecodeError) return @"DECODE ERROR";
- else if (ccStatus == kCCUnimplemented) return @"UNIMPLEMENTED"; */
- NSString *result;
- if (encryptOrDecrypt == kCCDecrypt)
- {
- result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr
- length:(NSUInteger)movedBytes]
- encoding:NSUTF8StringEncoding]
- autorelease];
- }
- else
- {
- NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
- result = [GTMBase64 stringByEncodingData:myData];
- }
- return result;
這個在網上也能搜索到詳細代碼。
但是要注意到一點:
- CCCrypt(encryptOrDecrypt,
- kCCAlgorithm3DES,
- kCCOptionPKCS7Padding | kCCOptionECBMode,
- vkey,
- kCCKeySize3DES,
- nil,
- vplainText,
- plainTextBufferSize,
- (void *)bufferPtr,
- bufferPtrSize,
- &movedBytes);
這個里面的參數可能會根據你服務端使用的對應的3des算法構造時參數的不同而需要自己調整。
比如我在網上看到的這個第三個參數只是用了kCCOptionPKCS7Padding,第六個可選參數用了上面一個自定義的iv。
但是這邊根據服務器,這個參數是nil才對應。
這邊也附上java端的加解密代碼
- public String encryptThreeDESECB(String src,String key) throws Exception
- {
- DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));
- SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
- SecretKey securekey = keyFactory.generateSecret(dks);
- Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
- cipher.init(Cipher.ENCRYPT_MODE, securekey);
- byte[] b=cipher.doFinal(src.getBytes());
- BASE64Encoder encoder = new BASE64Encoder();
- return encoder.encode(b).replaceAll("\r", "").replaceAll("\n", "");
- }
- //3DESECB解密,key必須是長度大於等於 3*8 = 24 位
- public String decryptThreeDESECB(String src,String key) throws Exception
- {
- //--通過base64,將字符串轉成byte數組
- BASE64Decoder decoder = new BASE64Decoder();
- byte[] bytesrc = decoder.decodeBuffer(src);
- //--解密的key
- DESedeKeySpec dks = new DESedeKeySpec(key.getBytes("UTF-8"));
- SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
- SecretKey securekey = keyFactory.generateSecret(dks);
- //--Chipher對象解密
- Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
- cipher.init(Cipher.DECRYPT_MODE, securekey);
- byte[] retByte = cipher.doFinal(bytesrc);
- return new String(retByte);
- }
內容也很少,這這么點。
然后是key,也就是共用密鑰的客戶端和服務端都保存一個。
簡單從數據傳輸來說,密文傳輸了,安全性相對來說提高了不少。
但是如果破解了客戶端代碼,那么其實密鑰也就暴露了。
這對於android上面來說,因為反編譯額純在,安全性不敢恭維,
ios的貌似好一點,因為暫未聽說反編譯ios的app的。
以上就是一種簡單的通信加密方案。
當然,其實這些其實算是通用技術~