通訊加解密基本算是每個涉及到使用者資訊的用戶端都會用到的一個技術。
一般我們可能就做簡單的防篡改和密文加密。
很多時候做一個加密只不過是一個小小的心理安慰吧了,因為純粹的從安全形度來說,安全性真的不高。
對於一些手機支付以及銀聯的用戶端,我看到有用的認證什麼來實現。
因為沒做過,所以也不是太瞭解。
這邊就說下最簡單的加密方案。
一: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的。
以上就是一種簡單的通訊加密方案。
當然,其實這些其實算是通用技術~