幾種常見加密算法初窺及如何選用加密算法


以前寫文章總喜歡先廢話一堆,這次就免了,直入主題。

加 密算法通常分爲對稱性加密算法和非對稱性加密算法,對於對稱性加密算法,信息接收雙方都需事先知道密匙和加解密算法且其密匙是相同的,之後便是對數據進行 加解密了。非對稱算法與之不同,發送雙方A,B事先均生成一堆密匙,然後A將自己的公有密匙發送給B,B將自己的公有密匙發送給A,如果A要給B發送消 息,則先需要用B的公有密匙進行消息加密,然後發送給B端,此時B端再用自己的私有密匙進行消息解密,B向A發送消息時爲同樣的道理。

幾種對稱性加密算法:AES,DES,3DES

DES是一種分組數據加密技術(先將數據分成固定長度的小數據塊,之後進行加密),速度較快,適用於大量數據加密,而3DES是一種基於DES的加密算法,使用3個不同密匙對同一個分組數據塊進行3次加密,如此以使得密文強度更高。

相較於DES和3DES算法而言,AES算法有着更高的速度和資源使用效率,安全級別也較之更高了,被稱爲下一代加密標準。

幾種非對稱性加密算法:RSA,DSA,ECC

RSA和DSA的安全性及其它各方面性能都差不多,而ECC較之則有着很多的性能優越,包括處理速度,帶寬要求,存儲空間等等。

幾種線性散列算法(簽名算法):MD5,SHA1,HMAC

這幾種算法只生成一串不可逆的密文,經常用其效驗數據傳輸過程中是否經過修改,因爲相同的生成算法對於同一明文只會生成唯一的密文,若相同算法生成的密文不同,則證明傳輸數據進行過了修改。通常在數據傳說過程前,使用MD5和SHA1算法均需要發送和接收數據雙方在數據傳送之前就知道密匙生成算法,而HMAC與之不同的是需要生成一個密匙,發送方用此密匙對數據進行摘要處理(生成密文),接收方再利用此密匙對接收到的數據進行摘要處理,再判斷生成的密文是否相同。

對於各種加密算法的選用:

由於對稱加密算法的密鑰管理是一個複雜的過程,密鑰的管理直接決定着他的安全性,因此當數據量很小時,我們可以考慮採用非對稱加密算法。

在實際的操作過程中,我們通常採用的方式是:採用非對稱加密算法管理對稱算法的密鑰,然後用對稱加密算法加密數據,這樣我們就集成了兩類加密算法的優點,既實現了加密速度快的優點,又實現了安全方便管理密鑰的優點。

如果在選定了加密算法後,那採用多少位的密鑰呢?一般來說,密鑰越長,運行的速度就越慢,應該根據的我們實際需要的安全級別來選擇,一般來說,RSA建議採用1024位的數字,ECC建議採用160位,AES採用128爲即可。


對於幾種加密算法的內部實現原理,我不想研究的太透徹,這些問題就留給科學家們去研究吧。而對於其實現而言,網上有很多開源版本,比較經典的是PorlaSSL(官網:http://en.wikipedia.org/wiki/PolarSSL )。其它語言如JAVA,OBJC也都有相應的類庫可以使用。以下附上自己用OC封裝的通用加密類:


  1. CryptionUseSysLib.h 
  2.  
  3. // 
  4. // CryptionUseSysLib.h 
  5. // encoding 
  6. // 
  7. // Created by weiy on 12-7-25. 
  8. // Copyright (c) 2012年 __MyCompanyName__. All rights reserved. 
  9. // 
  10.  
  11. #import <Foundation/Foundation.h> 
  12. #import <CommonCrypto/CommonDigest.h> 
  13. #import <CommonCrypto/CommonCryptor.h> 
  14.  
  15. @interface CryptionUseSysLib : NSObject{ 
  16.  
  17.  
  18. + (NSData *) md5:(NSString *)str; 
  19.  
  20.  
  21. + (NSData *) doCipherUseAesMethod:(NSData *)sTextIn 
  22.                                 key:(NSData *)sKey 
  23.                             context:(CCOperation)encryptOrDecrypt; 
  24.  
  25. + (NSData *) doCipherUse3DesMethod:(NSData *)sTextIn 
  26.                                 key:(NSData *)sKey 
  27.                             context:(CCOperation)encryptOrDecrypt; 
  28.  
  29. + (NSData *) doCipherUseDesMethod:(NSData *)sTextIn 
  30.                                 key:(NSData *)sKey 
  31.                             context:(CCOperation)encryptOrDecrypt; 
  32.  
  33. + (NSData *) doCipherUseCastMethod:(NSData *)sTextIn 
  34.                               key:(NSData *)sKey 
  35.                           context:(CCOperation)encryptOrDecrypt; 
  36.  
  37. + (NSString *) encodeBase64WithString:(NSString *)strData; 
  38.  
  39. + (NSString *) encodeBase64WithData:(NSData *)objData; 
  40.  
  41. + (NSData *) decodeBase64WithString:(NSString *)strBase64; 
  42.  
  43. @end 



  1. CryptionUseSysLib.m 
  2. // 
  3. // CryptionUseSysLib.m 
  4. // encoding 
  5. // 
  6. // Created by weiy on 12-7-25. 
  7. // Copyright (c) 2012年 __MyCompanyName__. All rights reserved. 
  8. // 
  9.  
  10. #import "CryptionUseSysLib.h" 
  11.  
  12.  
  13. static const char _base64EncodingTable[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  14. static const short _base64DecodingTable[256] = { 
  15. -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -1, -1, -2, -2, 
  16. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
  17. -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63, 
  18. 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2, 
  19. -2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 
  20. 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2, 
  21. -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 
  22. 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2, 
  23. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
  24. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
  25. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
  26. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
  27. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
  28. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
  29. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
  30. -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2 
  31. }; 
  32.  
  33. @implementation CryptionUseSysLib 
  34.  
  35.  
  36. + (NSString *) md5:(NSString *)str 
  37.  
  38.  
  39. const char *cStr = [str UTF8String]; 
  40.  
  41. unsigned char result[CC_MD5_DIGEST_LENGTH]; 
  42.  
  43. CC_MD5( cStr, strlen(cStr), result ); 
  44.  
  45. return [NSString 
  46.            
  47.           stringWithFormat: @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X"
  48.            
  49.           result[0], result[1], 
  50.            
  51.           result[2], result[3], 
  52.            
  53.           result[4], result[5], 
  54.            
  55.           result[6], result[7], 
  56.            
  57.           result[8], result[9], 
  58.            
  59.           result[10], result[11], 
  60.            
  61.           result[12], result[13], 
  62.            
  63.           result[14], result[15] 
  64.            
  65.           ]; 
  66.  
  67.  
  68. + (NSData *)doCipher:(NSData *)sTextIn 
  69.                  key:(NSData *)sKey 
  70.            Algorithm:(CCAlgorithm)algorithm 
  71.              context:(CCOperation)encryptOrDecrypt { 
  72.  
  73.   NSData * dTextIn; 
  74.    
  75.   dTextIn = [sTextIn mutableCopy]; 
  76.    
  77.   NSMutableData * dKey = [sKey mutableCopy]; 
  78.   int moreSize = 0; 
  79.    
  80.   //make key to standard; 
  81.   switch (algorithm) { 
  82.     case kCCAlgorithmDES: 
  83.       moreSize = kCCBlockSizeDES; 
  84.       [dKey setLength:kCCKeySizeDES]; 
  85.       break
  86.     case kCCAlgorithm3DES: 
  87.       moreSize = kCCBlockSize3DES; 
  88.       [dKey setLength:kCCKeySize3DES]; 
  89.       break
  90.     case kCCAlgorithmAES128: 
  91.       moreSize = kCCBlockSizeAES128; 
  92.       [dKey setLength:kCCKeySizeAES128]; 
  93.       break
  94.     case kCCAlgorithmCAST: 
  95.       moreSize = kCCBlockSizeCAST; 
  96.       [dKey setLength:kCCKeySizeMaxCAST]; 
  97.       break
  98.     case kCCAlgorithmRC4: 
  99.     case kCCAlgorithmRC2: 
  100.       moreSize = kCCBlockSizeRC2; 
  101.       [dKey setLength:kCCKeySizeMaxRC2]; 
  102.        break
  103.     default
  104.       return nil; 
  105.       break
  106.   } 
  107.    
  108.   uint8_t *bufferPtr1 = NULL; 
  109.   size_t bufferPtrSize1 = 0; 
  110.   size_t movedBytes1 = 0; 
  111. unsigned char iv[8]; 
  112.   memset(iv, 0, 8); 
  113.    
  114.   bufferPtrSize1 = [sTextIn length] + moreSize; 
  115.  
  116.   bufferPtr1 = malloc(bufferPtrSize1); 
  117.   memset((void *)bufferPtr1, 0, bufferPtrSize1); 
  118.    
  119.   // cryption.... 
  120.   CCCryptorStatus ccStatus = CCCrypt(encryptOrDecrypt, // CCOperation op 
  121.           algorithm, // CCAlgorithm alg 
  122.           kCCOptionPKCS7Padding|kCCOptionECBMode, // CCOptions options 
  123.           [dKey bytes], // const void *key 
  124.           [dKey length], // size_t keyLength 
  125.           iv, // const void *iv 
  126.           [dTextIn bytes], // const void *dataIn 
  127.           [dTextIn length], // size_t dataInLength 
  128.           (void *)bufferPtr1, // void *dataOut 
  129.           bufferPtrSize1, // size_t dataOutAvailable 
  130.           &movedBytes1); // size_t *dataOutMoved 
  131.    
  132.   // output situation after crypt 
  133.   switch (ccStatus) { 
  134.     case kCCSuccess: 
  135.       NSLog(@"SUCCESS"); 
  136.       break
  137.     case kCCParamError: 
  138.       NSLog(@"PARAM ERROR"); 
  139.       break
  140.     case kCCBufferTooSmall: 
  141.       NSLog(@"BUFFER TOO SMALL"); 
  142.       break
  143.     case kCCMemoryFailure: 
  144.       NSLog(@"MEMORY FAILURE"); 
  145.       break
  146.     case kCCAlignmentError: 
  147.       NSLog(@"ALIGNMENT ERROR"); 
  148.       break
  149.     case kCCDecodeError: 
  150.       NSLog(@"DECODE ERROR"); 
  151.       break
  152.     case kCCUnimplemented: 
  153.       NSLog(@"UNIMPLEMENTED"); 
  154.       break
  155.     default
  156.       break
  157.   } 
  158.    
  159.   if (ccStatus == kCCSuccess){ 
  160.     NSData *result = [NSData dataWithBytes:bufferPtr1 length:movedBytes1]; 
  161.     free(bufferPtr1); 
  162.     return result; 
  163.   } 
  164.   free(bufferPtr1); 
  165.   return nil; 
  166.  
  167. + (NSData*)doCipherUse3DesMethod:(NSData *)sTextIn 
  168.                                key:(NSData *)sKey 
  169.                            context:(CCOperation)encryptOrDecrypt{ 
  170.   return [CryptionUseSysLib doCipher:sTextIn 
  171.                     key:sKey 
  172.               Algorithm:kCCAlgorithm3DES context:encryptOrDecrypt]; 
  173.  
  174. + (NSData *) doCipherUseCastMethod:(NSData *)sTextIn 
  175.                               key:(NSData *)sKey 
  176.                           context:(CCOperation)encryptOrDecrypt{ 
  177.    
  178.   return [CryptionUseSysLib doCipher:sTextIn 
  179.                                  key:sKey 
  180.                            Algorithm:kCCAlgorithmCAST context:encryptOrDecrypt]; 
  181.  
  182.  
  183. + (NSData*)doCipherUseDesMethod:(NSData *)sTextIn 
  184.                               key:(NSData *)sKey 
  185.                           context:(CCOperation)encryptOrDecrypt{ 
  186.   return [CryptionUseSysLib doCipher:sTextIn 
  187.                     key:sKey 
  188.               Algorithm:kCCAlgorithmDES 
  189.                 context:encryptOrDecrypt]; 
  190.  
  191. + (NSData*)doCipherUseAesMethod:(NSData *)sTextIn 
  192.                               key:(NSData *)sKey 
  193.                           context:(CCOperation)encryptOrDecrypt{ 
  194.   return [CryptionUseSysLib doCipher:sTextIn 
  195.                     key:sKey 
  196.               Algorithm:kCCAlgorithmAES128 
  197.                 context:encryptOrDecrypt]; 
  198.  
  199. + (NSString *)encodeBase64WithString:(NSString *)strData { 
  200. return [CryptionUseSysLib encodeBase64WithData:[strData dataUsingEncoding:NSUTF8StringEncoding]]; 
  201.  
  202. + (NSString *)encodeBase64WithData:(NSData *)objData { 
  203.  
  204. const unsigned char * objRawData = [objData bytes]; 
  205. char * objPointer; 
  206. char * strResult; 
  207.  
  208. // Get the Raw Data length and ensure we actually have data 
  209. int intLength = [objData length]; 
  210. if (intLength == 0) return nil; 
  211.  
  212. // Setup the String-based Result placeholder and pointer within that placeholder 
  213. strResult = (char *)calloc(((intLength + 2) / 3) * 4, sizeof(char)); 
  214. objPointer = strResult; 
  215.  
  216. // Iterate through everything 
  217. while (intLength > 2) { // keep going until we have less than 24 bits 
  218. *objPointer++ = _base64EncodingTable[objRawData[0] >> 2]; 
  219. *objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)]; 
  220. *objPointer++ = _base64EncodingTable[((objRawData[1] & 0x0f) << 2) + (objRawData[2] >> 6)]; 
  221. *objPointer++ = _base64EncodingTable[objRawData[2] & 0x3f]; 
  222.  
  223. // we just handled 3 octets (24 bits) of data 
  224. objRawData += 3; 
  225. intLength -= 3; 
  226.  
  227. // now deal with the tail end of things 
  228. if (intLength != 0) { 
  229. *objPointer++ = _base64EncodingTable[objRawData[0] >> 2]; 
  230. if (intLength > 1) { 
  231. *objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)]; 
  232. *objPointer++ = _base64EncodingTable[(objRawData[1] & 0x0f) << 2]; 
  233. *objPointer++ = '='
  234. else { 
  235. *objPointer++ = _base64EncodingTable[(objRawData[0] & 0x03) << 4]; 
  236. *objPointer++ = '='
  237. *objPointer++ = '='
  238.  
  239. // Terminate the string-based result 
  240. *objPointer = '\0'
  241.  
  242. // Return the results as an NSString object 
  243. return [NSString stringWithCString:strResult encoding:NSASCIIStringEncoding]; 
  244.  
  245. + (NSData *)decodeBase64WithString:(NSString *)strBase64 { 
  246. const char * objPointer = [strBase64 cStringUsingEncoding:NSASCIIStringEncoding]; 
  247. int intLength = strlen(objPointer); 
  248. int intCurrent; 
  249. int i = 0, j = 0, k; 
  250.  
  251. unsigned char * objResult; 
  252. objResult = calloc(intLength, sizeof(char)); 
  253.  
  254. // Run through the whole string, converting as we go 
  255. while ( ((intCurrent = *objPointer++) != '\0') && (intLength-- > 0) ) { 
  256. if (intCurrent == '=') { 
  257. if (*objPointer != '=' && ((i % 4) == 1)) {// || (intLength > 0)) { 
  258. // the padding character is invalid at this point -- so this entire string is invalid 
  259. free(objResult); 
  260. return nil; 
  261. continue
  262.  
  263. intCurrent = _base64DecodingTable[intCurrent]; 
  264. if (intCurrent == -1) { 
  265. // we're at a whitespace -- simply skip over 
  266. continue
  267. else if (intCurrent == -2) { 
  268. // we're at an invalid character 
  269. free(objResult); 
  270. return nil; 
  271.  
  272. switch (i % 4) { 
  273. case 0: 
  274. objResult[j] = intCurrent << 2; 
  275. break
  276.  
  277. case 1: 
  278. objResult[j++] |= intCurrent >> 4; 
  279. objResult[j] = (intCurrent & 0x0f) << 4; 
  280. break
  281.  
  282. case 2: 
  283. objResult[j++] |= intCurrent >>2; 
  284. objResult[j] = (intCurrent & 0x03) << 6; 
  285. break
  286.  
  287. case 3: 
  288. objResult[j++] |= intCurrent; 
  289. break
  290. i++; 
  291.  
  292. // mop things up if we ended on a boundary 
  293. k = j; 
  294. if (intCurrent == '=') { 
  295. switch (i % 4) { 
  296. case 1: 
  297. // Invalid state 
  298. free(objResult); 
  299. return nil; 
  300.  
  301. case 2: 
  302. k++; 
  303. // flow through 
  304. case 3: 
  305. objResult[k] = 0; 
  306.  
  307. // Cleanup and setup the return NSData 
  308. NSData * objData = [[[NSData alloc] initWithBytes:objResult length:j] autorelease]; 
  309. free(objResult); 
  310. return objData; 
  311.  
  312. @end 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章