1. 程式人生 > >幾種常用的密碼加密演算法以及選用

幾種常用的密碼加密演算法以及選用

原連結:http://www.cnblogs.com/yangywyangyw/archive/2012/07/31/2620861.html

加 密演算法通常分為對稱性加密演算法和非對稱性加密演算法,對於對稱性加密演算法,資訊接收雙方都需事先知道密匙和加解密演算法且其密匙是相同的,之後便是對資料進行 加解密了。非對稱演算法與之不同,傳送雙方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封裝的通用加密類:

複製程式碼
CryptionUseSysLib.h 
     
    // 
    // CryptionUseSysLib.h 
    // encoding 
    // 
    // Created by weiy on 12-7-25. 
    // Copyright (c) 2012年 __MyCompanyName__. All rights reserved. 
    // 
     
    #import <Foundation/Foundation.h> 
    #import <CommonCrypto/CommonDigest.h> 
    #import <CommonCrypto/CommonCryptor.h> 
     
    @interface CryptionUseSysLib : NSObject{ 
     
    } 
     
    + (NSData *) md5:(NSString *)str; 
     
     
    + (NSData *) doCipherUseAesMethod:(NSData *)sTextIn 
                                    key:(NSData *)sKey 
                                context:(CCOperation)encryptOrDecrypt; 
     
    + (NSData *) doCipherUse3DesMethod:(NSData *)sTextIn 
                                    key:(NSData *)sKey 
                                context:(CCOperation)encryptOrDecrypt; 
     
    + (NSData *) doCipherUseDesMethod:(NSData *)sTextIn 
                                    key:(NSData *)sKey 
                                context:(CCOperation)encryptOrDecrypt; 
     
    + (NSData *) doCipherUseCastMethod:(NSData *)sTextIn 
                                  key:(NSData *)sKey 
                              context:(CCOperation)encryptOrDecrypt; 
     
    + (NSString *) encodeBase64WithString:(NSString *)strData; 
     
    + (NSString *) encodeBase64WithData:(NSData *)objData; 
     
    + (NSData *) decodeBase64WithString:(NSString *)strBase64; 
     
    @end 
複製程式碼複製程式碼
CryptionUseSysLib.m 
    // 
    // CryptionUseSysLib.m 
    // encoding 
    // 
    // Created by weiy on 12-7-25. 
    // Copyright (c) 2012年 __MyCompanyName__. All rights reserved. 
    // 
     
    #import "CryptionUseSysLib.h" 
     
     
    static const char _base64EncodingTable[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 
    static const short _base64DecodingTable[256] = { 
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -1, -1, -2, -1, -1, -2, -2, 
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
    -1, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 62, -2, -2, -2, 63, 
    52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -2, -2, -2, -2, -2, -2, 
    -2, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 
    15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -2, -2, -2, -2, -2, 
    -2, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 
    41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -2, -2, -2, -2, -2, 
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, 
    -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2, -2 
    }; 
     
    @implementation CryptionUseSysLib 
     
     
    + (NSString *) md5:(NSString *)str 
     
    { 
     
    const char *cStr = [str UTF8String]; 
     
    unsigned char result[CC_MD5_DIGEST_LENGTH]; 
     
    CC_MD5( cStr, strlen(cStr), result ); 
     
    return [NSString 
               
              stringWithFormat: @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", 
               
              result[0], result[1], 
               
              result[2], result[3], 
               
              result[4], result[5], 
               
              result[6], result[7], 
               
              result[8], result[9], 
               
              result[10], result[11], 
               
              result[12], result[13], 
               
              result[14], result[15] 
               
              ]; 
     
    } 
     
    + (NSData *)doCipher:(NSData *)sTextIn 
                     key:(NSData *)sKey 
               Algorithm:(CCAlgorithm)algorithm 
                 context:(CCOperation)encryptOrDecrypt { 
     
      NSData * dTextIn; 
       
      dTextIn = [sTextIn mutableCopy]; 
       
      NSMutableData * dKey = [sKey mutableCopy]; 
      int moreSize = 0; 
       
      //make key to standard; 
      switch (algorithm) { 
        case kCCAlgorithmDES: 
          moreSize = kCCBlockSizeDES; 
          [dKey setLength:kCCKeySizeDES]; 
          break; 
        case kCCAlgorithm3DES: 
          moreSize = kCCBlockSize3DES; 
          [dKey setLength:kCCKeySize3DES]; 
          break; 
        case kCCAlgorithmAES128: 
          moreSize = kCCBlockSizeAES128; 
          [dKey setLength:kCCKeySizeAES128]; 
          break; 
        case kCCAlgorithmCAST: 
          moreSize = kCCBlockSizeCAST; 
          [dKey setLength:kCCKeySizeMaxCAST]; 
          break; 
        case kCCAlgorithmRC4: 
        case kCCAlgorithmRC2: 
          moreSize = kCCBlockSizeRC2; 
          [dKey setLength:kCCKeySizeMaxRC2]; 
           break; 
        default: 
          return nil; 
          break; 
      } 
       
      uint8_t *bufferPtr1 = NULL; 
      size_t bufferPtrSize1 = 0; 
      size_t movedBytes1 = 0; 
    unsigned char iv[8]; 
      memset(iv, 0, 8); 
       
      bufferPtrSize1 = [sTextIn length] + moreSize; 
     
      bufferPtr1 = malloc(bufferPtrSize1); 
      memset((void *)bufferPtr1, 0, bufferPtrSize1); 
       
      // cryption.... 
      CCCryptorStatus ccStatus = CCCrypt(encryptOrDecrypt, // CCOperation op 
              algorithm, // CCAlgorithm alg 
              kCCOptionPKCS7Padding|kCCOptionECBMode, // CCOptions options 
              [dKey bytes], // const void *key 
              [dKey length], // size_t keyLength 
              iv, // const void *iv 
              [dTextIn bytes], // const void *dataIn 
              [dTextIn length], // size_t dataInLength 
              (void *)bufferPtr1, // void *dataOut 
              bufferPtrSize1, // size_t dataOutAvailable 
              &movedBytes1); // size_t *dataOutMoved 
       
      // output situation after crypt 
      switch (ccStatus) { 
        case kCCSuccess: 
          NSLog(@"SUCCESS"); 
          break; 
        case kCCParamError: 
          NSLog(@"PARAM ERROR"); 
          break; 
        case kCCBufferTooSmall: 
          NSLog(@"BUFFER TOO SMALL"); 
          break; 
        case kCCMemoryFailure: 
          NSLog(@"MEMORY FAILURE"); 
          break; 
        case kCCAlignmentError: 
          NSLog(@"ALIGNMENT ERROR"); 
          break; 
        case kCCDecodeError: 
          NSLog(@"DECODE ERROR"); 
          break; 
        case kCCUnimplemented: 
          NSLog(@"UNIMPLEMENTED"); 
          break; 
        default: 
          break; 
      } 
       
      if (ccStatus == kCCSuccess){ 
        NSData *result = [NSData dataWithBytes:bufferPtr1 length:movedBytes1]; 
        free(bufferPtr1); 
        return result; 
      } 
      free(bufferPtr1); 
      return nil; 
    } 
     
    + (NSData*)doCipherUse3DesMethod:(NSData *)sTextIn 
                                   key:(NSData *)sKey 
                               context:(CCOperation)encryptOrDecrypt{ 
      return [CryptionUseSysLib doCipher:sTextIn 
                        key:sKey 
                  Algorithm:kCCAlgorithm3DES context:encryptOrDecrypt]; 
    } 
     
    + (NSData *) doCipherUseCastMethod:(NSData *)sTextIn 
                                  key:(NSData *)sKey 
                              context:(CCOperation)encryptOrDecrypt{ 
       
      return [CryptionUseSysLib doCipher:sTextIn 
                                     key:sKey 
                               Algorithm:kCCAlgorithmCAST context:encryptOrDecrypt]; 
     
    } 
     
    + (NSData*)doCipherUseDesMethod:(NSData *)sTextIn 
                                  key:(NSData *)sKey 
                              context:(CCOperation)encryptOrDecrypt{ 
      return [CryptionUseSysLib doCipher:sTextIn 
                        key:sKey 
                  Algorithm:kCCAlgorithmDES 
                    context:encryptOrDecrypt]; 
    } 
     
    + (NSData*)doCipherUseAesMethod:(NSData *)sTextIn 
                                  key:(NSData *)sKey 
                              context:(CCOperation)encryptOrDecrypt{ 
      return [CryptionUseSysLib doCipher:sTextIn 
                        key:sKey 
                  Algorithm:kCCAlgorithmAES128 
                    context:encryptOrDecrypt]; 
    } 
     
    + (NSString *)encodeBase64WithString:(NSString *)strData { 
    return [CryptionUseSysLib encodeBase64WithData:[strData dataUsingEncoding:NSUTF8StringEncoding]]; 
    } 
     
    + (NSString *)encodeBase64WithData:(NSData *)objData { 
     
    const unsigned char * objRawData = [objData bytes]; 
    char * objPointer; 
    char * strResult; 
     
    // Get the Raw Data length and ensure we actually have data 
    int intLength = [objData length]; 
    if (intLength == 0) return nil; 
     
    // Setup the String-based Result placeholder and pointer within that placeholder 
    strResult = (char *)calloc(((intLength + 2) / 3) * 4, sizeof(char)); 
    objPointer = strResult; 
     
    // Iterate through everything 
    while (intLength > 2) { // keep going until we have less than 24 bits 
    *objPointer++ = _base64EncodingTable[objRawData[0] >> 2]; 
    *objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)]; 
    *objPointer++ = _base64EncodingTable[((objRawData[1] & 0x0f) << 2) + (objRawData[2] >> 6)]; 
    *objPointer++ = _base64EncodingTable[objRawData[2] & 0x3f]; 
     
    // we just handled 3 octets (24 bits) of data 
    objRawData += 3; 
    intLength -= 3; 
    } 
     
    // now deal with the tail end of things 
    if (intLength != 0) { 
    *objPointer++ = _base64EncodingTable[objRawData[0] >> 2]; 
    if (intLength > 1) { 
    *objPointer++ = _base64EncodingTable[((objRawData[0] & 0x03) << 4) + (objRawData[1] >> 4)]; 
    *objPointer++ = _base64EncodingTable[(objRawData[1] & 0x0f) << 2]; 
    *objPointer++ = '='; 
    } else { 
    *objPointer++ = _base64EncodingTable[(objRawData[0] & 0x03) << 4]; 
    *objPointer++ = '='; 
    *objPointer++ = '='; 
    } 
    } 
     
    // Terminate the string-based result 
    *objPointer = '\0'; 
     
    // Return the results as an NSString object 
    return [NSString stringWithCString:strResult encoding:NSASCIIStringEncoding]; 
    } 
     
    + (NSData *)decodeBase64WithString:(NSString *)strBase64 { 
    const char * objPointer = [strBase64 cStringUsingEncoding:NSASCIIStringEncoding]; 
    int intLength = strlen(objPointer); 
    int intCurrent; 
    int i = 0, j = 0, k; 
     
    unsigned char * objResult; 
    objResult = calloc(intLength, sizeof(char)); 
     
    // Run through the whole string, converting as we go 
    while ( ((intCurrent = *objPointer++) != '\0') && (intLength-- > 0) ) { 
    if (intCurrent == '=') { 
    if (*objPointer != '=' && ((i % 4) == 1)) {// || (intLength > 0)) { 
    // the padding character is invalid at this point -- so this entire string is invalid 
    free(objResult); 
    return nil; 
    } 
    continue; 
    } 
     
    intCurrent = _base64DecodingTable[intCurrent]; 
    if (intCurrent == -1) { 
    // we're at a whitespace -- simply skip over 
    continue; 
    } else if (intCurrent == -2) { 
    // we're at an invalid character 
    free(objResult); 
    return nil; 
    } 
     
    switch (i % 4) { 
    case 0: 
    objResult[j] = intCurrent << 2; 
    break; 
     
    case 1: 
    objResult[j++] |= intCurrent >> 4; 
    objResult[j] = (intCurrent & 0x0f) << 4; 
    break; 
     
    case 2: 
    objResult[j++] |= intCurrent >>2; 
    objResult[j] = (intCurrent & 0x03) << 6; 
    break; 
     
    case 3: 
    objResult[j++] |= intCurrent; 
    break; 
    } 
    i++; 
    } 
     
    // mop things up if we ended on a boundary 
    k = j; 
    if (intCurrent == '=') { 
    switch (i % 4) { 
    case 1: 
    // Invalid state 
    free(objResult); 
    return nil; 
     
    case 2: 
    k++; 
    // flow through 
    case 3: 
    objResult[k] = 0; 
    } 
    } 
     
    // Cleanup and setup the return NSData 
    NSData * objData = [[[NSData alloc] initWithBytes:objResult length:j] autorelease]; 
    free(objResult); 
    return objData; 
    } 
     
@end 

相關推薦

常用密碼加密演算法以及選用

原連結:http://www.cnblogs.com/yangywyangyw/archive/2012/07/31/2620861.html加 密演算法通常分為對稱性加密演算法和非對稱性加密演算法,對於對稱性加密演算法,資訊接收雙方都需事先知道密匙和加解密演算法且其密匙是相

常用的排序演算法

什麼是演算法 我想很多程式設計師恐怕誤解了「演算法」的意義,一想到演算法就是動態規劃,機器學習之類的高大名詞。演算法其實就是數學中的「解題過程」,解題過程要求精確,考慮各種情況,需要人看得懂。演算法不需要你在鍵盤上選擇什麼程式語言實現,只需要在本子上詳細的寫出每一個步驟就可以了。 演算法真的很重要嗎?

C#常用加密方式

read int ati htop 磁盤 tarray dem new lac 一、AES加密算法 AES算法基於排列和置換運算。排列是對數據重新進行安排,置換是將一個數據單元替換為另一個。AES 使用幾種不同的方法來執行排列和置換運算。 AES是一個叠代的、對稱

常用的排序演算法(c語言實現)

概述 最近重新回顧了一下資料結構和演算法的一些基本知識,對幾種排序演算法有了更多的理解,也趁此機會通過部落格做一個總結。 1.選擇排序-簡單選擇排序 選擇排序是最簡單的一種基於O(n2)時間複雜度的排序演算法,基本思想是從i=0位置開始到i=n-1

常用的排序演算法(快速排序,希爾排序,堆排序,選擇排序,氣泡排序)

1、歸併排序      基本原理:歸併排序也稱合併排序,其演算法思想是將待排序序列分為兩部分,依次對分得的兩個部分再次使用歸併排序,之後再對其進行合併。操作步驟如下。(1)將所要進行的排序序列分為左右兩個部分,如果要進行排序的序列的起始元素下標為first,最後一個元素的

常用的排序演算法(一)--python實現

1. 選擇排序,時間複雜度O(n^2),演算法不穩定。     思路:(1)迴圈整個陣列 arr,選出最大的數,將它放在空陣列 new_arr 的第一個位置。                (2)將剛

常見的加密演算法及 Java 實現

介紹 本文主要對加密演算法做個概況性的介紹,然後給出幾種簡單的加密演算法 Java 實現。 1. 演算法種類 單向加密 對稱加密 非對稱加密 1.1 單向加密 即加密之後不能解密,一般用於資料驗證 1) Base64 Base64

Python中time模塊和datetime模塊的常用操作以及常用時間格式間的轉換

pyrhon time datatime 幾種常用時間格式的轉換 最常見以及常用的幾種時間格式 1、時間戳(timestamp),時間戳表示的是從1970年1月1日00:00:00開始按秒計算的偏移量。 2、時間元組(struct_time),共有九個元素組。 3、格式化時間(fo

對於單向連結串列的10常用演算法

list.c檔案如下 #include "list.h" /*返回head連結串列POS節點的位置*/ LINK list_moov_pos(LINK head,int pos){ LINK node = head; while(--pos) node = node->pNe

aiax的請求過程以及在jquery中的常用使用方式

在Java後端專案的開發過程中,由於涉及前端相關的東西,會經常遇到ajax請求的形式,學習一下,可以在開發後端的過程中更加的流暢。 ajax:Asynchronous JavaScript and XML 1、原始方法請求 function load(){    

scikit-learn常用演算法的比較(code)

from sklearn import datasets import numpy as np iris =datasets.load_iris() X = iris.data[:,[2,3]] y = iris.target np.unique(y) #np.unique(y)返回儲

java開發過程中常用演算法

排序演算法 排序演算法中包括:簡單排序、高階排序   簡單排序  簡單排序常用的有:氣泡排序、選擇排序、插入排序 氣泡排序程式碼如下: 1 private static void bubbleSrot(int[] arr) { 2 3 for (int

常用排序演算法的思路和複雜度對比

1、插入排序——直接插入排序、希爾排序 (1)直接插入排序思路:從第1號元素開始,每個元素依次與前面的元素做比較,小的排前面,這樣當比較到最後一 個元 素完即完成排序。 (2)希爾排序思路:     

轉Hash演算法解決衝突的方法一般有以下常用的解決方法

Hash演算法解決衝突的方法一般有以下幾種常用的解決方法  1, 開放定址法:  所謂的開放定址法就是一旦發生了衝突,就去尋找下一個空的雜湊地址,只要散列表足夠大,空的雜湊地址總能找到,並將記錄存入  公式為:fi(key) = (f(key)+di) MOD m (di=1,2

常用迴歸演算法的比較

# -*- coding:utf-8 -*- import numpy as np import matplotlib.pyplot as plt import random def text2num(string):     str_list = string

Java陣列的常用操作方法(排序演算法及查詢)

陣列的查詢 查詢是在陣列中尋找特定元素的過程。 線性查詢法 線性查詢法將要查詢的關鍵字key與陣列中的元素逐個進行比較。如果匹配成功,線性查詢法則返回與關鍵字匹配的元素在陣列中的下標;如果沒有匹配成功,則返回-1。下面給出線性查詢法的程式: pr

常用排序演算法總結

選擇排序、快速排序、希爾排序、堆排序不是穩定的排序演算法,氣泡排序、插入排序、歸併排序和基數排序是穩定的排序演算法。 冒泡法:  這是最原始,也是眾所周知的最慢的演算法了。他的名字的由來因為它的工作看來象是冒泡:  複雜度為O(n*n)。當資料為正序,將不會有交換。複雜度為

計算幾何與圖形學有關的常用演算法(二)

3.6 用向量的叉積判斷直線段是否有交         向量叉積計算的另一個常用用途是直線段求交。求交演算法是計算機圖形學的核心演算法,也是體現速度和穩定性的重要標誌,高效並且穩定的求交演算法是任何一個CAD軟體都必需要重點關注的。求交包含兩層概念,一個是判斷是否相

算法系列之九:計算幾何與圖形學有關的常用演算法(二)

3.6 用向量的叉積判斷直線段是否有交        向量叉積計算的另一個常用用途是直線段求交。求交演算法是計算機圖形學的核心演算法,也是體現速度和穩定性的重要標誌,高效並且穩定的求交演算法是任何一個CAD軟體都必需要重點關注的。求交包含兩層概念,一個是判斷是否相交,另一個是

常用加密手段的加密與解密

網路中傳輸敏感資訊的時候通常會對字串做加密解密處理1.Base64位加密(可加密解密)    最簡單的加密方式,沒有金鑰,這種方式只要讓別人拿到你的密文,就可以直接解密,只能用來迷惑,一般情況下不單獨使用,因為真的並沒有什麼卵用~可以和其他加密方式混合起來,作為一層外部包裝。import base64data