iOS加密算法總結


 

常用加密算法


 

 

  • DES:Data Encryption Standard,即數據加密算法,它是IBM公司於1975年研究成功並公開發表的。
  • DES(數據加密標准)原理:

      DES是一個分組加密算法,它以64位為分組對數據加密。64位一組的明文從算法的一端輸入,64位的密文從另一段輸出。它是一個對稱算法:加密和解密用的是同一個算法。
      密鑰通常表示為64位的數,但每個第8位都用作奇偶校驗,可以忽略,所以密鑰長度為56位。密鑰可以是任意的56位的數,且可在任意的時候改變。
      DES算法只不過是加密的兩個基本技術——混亂和擴散的組合,即先代替后置換,它基於密鑰作用於明文,這是一輪(round),DES在明文分組上實施16輪相同的組合技術。

      DES現在用的比較少,因為它的加密強度不夠,能夠暴力破解!!還有一個3DES,原理和DES幾乎是一樣的,只是使用3個密鑰,對相同的數據執行三次加密,增強加密強度,但是要維護3個密鑰,大大增加了維護成本!

  • AES:高級加密標准,這個標准用來替代原先的DES,已經被多方分析且廣為全世界所使用。高級加密標准已然成為對稱密鑰加密中最流行的算法之一。
  • AES:高級加密原理:
    AES 是一個新的可以用於保護電子數據的加密算法。明確地說,AES 是一個迭代的、對稱密鑰分組的密碼,它可以使用128、192 和 256 位密鑰,並且用 128 位(16字節)分組加密和解密數據。與公共密鑰密碼使用密鑰對不同,對稱密鑰密碼使用相同的密鑰加密和解密數據。通過分組密碼返回的加密數據 的位數與輸入數據相同。迭代加密使用一個循環結構,在該循環中重復置換(permutations )和替換(substitutions)輸入數據。Figure 1 顯示了 AES 用192位密鑰對一個16位字節數據塊進行加密和解密的情形。

  • MD5:Message-Digest Algorithm 5(信息-摘要算法5),用於確保信息傳輸完整一致。是計算機廣泛使用的雜湊算法之一(又譯摘要算法、哈希算法),主流編程語言普遍已有MD5實現。這個應該是聽到最多的算法,據說是已經被破解了。但是我覺得破解這個應該也要很久吧!
  • MD5加密原理:
    對MD5算法簡要的敘述可以為:MD5以512位分組來處理輸入的信息,且每一分組又被划分為16個32位子分組,經過了一系列的處理后,算法的輸出由四個32位分組組成,將這四個32位分組級聯后將生成一個128位散列值
      目前破解MD5主要依靠大型字典的方法,將常用密碼進行MD5后建立數據庫,然后和MD5數值進行對比,通過這樣的方法來“破解”MD5,因此,通常直接將密碼進行MD5處理的話,
      一些弱密碼很容易可以通過這種手段“破解”出 來。不過,如果在散列的過程中,加入足夠長的salt(即干擾字符串),並且salt加入一些動態信息,例如username、隨機碼等,
      這樣生成的MD5還是很難被破解的,因為僅僅從數據庫無法看到MD5具體的處理過程,必須同時看到處理時的源代碼才可以,這就給破解MD5帶來相當大的難度。

  • Base64:Base64是網絡上最常見的用於傳輸8Bit字節代碼的編碼方式之一。Base64編碼可用於在HTTP環境下傳遞較長的標識信息。例如,在Java Persistence系統Hibernate中,就采用了Base64來將一個較長的唯一 標識符(一般為128-bit的UUID)編碼為一個字符串,用作HTTP表單和HTTP GET URL中的參數。在其應用程序中,也常常需要把二進制數據編碼為適合放在URL(包括隱藏表單域)中的形式。此時,采用Base64編碼具有不可讀性,即所編碼的數據不會被人用肉眼所直接看到。   

     

  • RSA 加密方式:

      RSA 加密方式相信每一個對接過支付寶SDK的同學都聽過這個RSA加密,因為支付寶SDK的加密方式采用的就是這種。

      它的一個大致額歷程是這樣:

      1、生成你的公鑰給支付寶,注冊支付寶SDK之后你也可以拿到支付寶公鑰。

      2、上傳你的公鑰到支付寶,用你的私鑰加密你的信息,支付包用你上傳的公鑰解密你傳給支付寶的信息。

      3、用你拿到的支付寶的公鑰解密支付寶回調給你的信息。

      注意:不要把這新秘鑰信息存放在客戶端,存放在服務端也建議不要使用明文的形式存儲,安全問題!有些說把秘鑰制作成.a文件的形式存放的客戶端,問題反編譯之后直接拿到你這份.a文件是不是也可以用用呢?

      RSA是目前最有影響力的公鑰加密算法,該算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但那時想要對其乘積進行因式分解卻極其困難,

      因此可以將乘積公開作為加密密鑰,即公鑰,而兩個大素數組合成私鑰。公鑰是可發布的供任何人使用,私鑰則為自己所有,供解密之用。

 

加密模式 


 

 

      我們通過下面的兩張圖解釋一下這倆種加密模式,因為在后面的代碼解讀中我們會涉及到這一點,要是不了解后面代碼中有些點可能會犯迷糊:

      ECB:電子密碼本,就是每個塊都是獨立加密的。 

 

      CBC:密碼塊鏈,使用一個密鑰和一個初始化向量(IV)對數據執行加密轉換。

       

 

重點說說它們的代碼部分 


 

   (首先說明DES由於自身的缺陷,就不再去研究看它的代碼了,我們這里研究的也不會特別深,主要是為了在項目中的使用)

     先說說這個類: CCCryptorStatus

     關於CCCryptorStatus,構造它可以使用CCCrypt CCCryptorCreateWithMode 、CCCryptorCreate等好多類構造,在使用這些類構造時對參數是比較多,我們看着它們的頭文件,解讀一下參數的含義,我們就用CCCrypt為例說明一下,下面是CCCrypt的結構代碼:

CCCryptorStatus CCCrypt(
    CCOperation op,         /* kCCEncrypt, etc. */
    CCAlgorithm alg,        /* kCCAlgorithmAES128, etc. */
    CCOptions options,      /* kCCOptionPKCS7Padding, etc. */
    const void *key,
    size_t keyLength,
    const void *iv,         /* optional initialization vector */
    const void *dataIn,     /* optional per op and alg */
    size_t dataInLength,
    void *dataOut,          /* data RETURNED here */
    size_t dataOutAvailable,
    size_t *dataOutMoved)
    __OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);

 

      理解了它的參數在我們寫AES加密代碼的時候是有很大的幫助的,下面是它的頭文件中Apple給的參數解釋,我們解釋一下:

 // 設置加密參數
        /*!
         @function   CCCrypt
         @abstract   Stateless, one-shot encrypt or decrypt operation.
         This basically performs a sequence of CCCrytorCreate(),
         CCCryptorUpdate(), CCCryptorFinal(), and CCCryptorRelease().
         
         @param      alg     Defines the encryption algorithm.定義加密的算法
         alg:
         enum {
         kCCAlgorithmAES128 = 0,
         kCCAlgorithmAES = 0,
         kCCAlgorithmDES,
         kCCAlgorithm3DES,
         kCCAlgorithmCAST,
         kCCAlgorithmRC4,
         kCCAlgorithmRC2,
         kCCAlgorithmBlowfish
         };
         
         
         @param      op         Defines the basic operation: kCCEncrypt or kCCDecrypt.  定義加密還是解密
         
         下面是補碼方式
         enum {
               kCCOptionPKCS7Padding   = 0x0001,
               kCCOptionECBMode        = 0x0002};
         @param      options    A word of flags defining options. See discussion for the CCOptions type.
         
         // 加密的key
         @param      key        Raw key material, length keyLength bytes.
         // 加密的key的長度
         @param      keyLength  Length of key material. Must be appropriate for the select algorithm. Some algorithms may
         provide for varying key lengths.
         
         
         // IV 向量
         @param      iv          Initialization vector, optional. Used for
                                 Cipher Block Chaining (CBC) mode. If present,
                                 must be the same length as the selected
                                 algorithm's block size. If CBC mode is
                                 selected (by the absence of any mode bits in
                                 the options flags) and no IV is present, a
                                 NULL (all zeroes) IV will be used. This is
                                 ignored if ECB mode is used or if a stream
                                 cipher algorithm is selected. For sound encryption,
                                 always initialize IV with random data.
         
                                 IV向量:大概意思說,此屬性可選,但只能用於CBC模式。
                                 如果出現那么他的長度必須和算法的block size保持一致。
                                 如果是因為默認選擇的CBC模式而且向量沒有定義,那么向量會被定義為NULL。
                                 如果選擇了ECB模式或是其他的流密碼算法,之前所說的邏輯都不成立。
         
                                 NOTE**** 如果你想使用密鑰偏移量IV 那你的加密模式必須為CBC,不能使用別的模式
         
         // 需要加密或者解密處理的data以及data的長度
         @param      dataIn          Data to encrypt or decrypt, length dataInLength bytes.
         @param      dataInLength    Length of data to encrypt or decrypt.
         
         // 加密或者解密后的數據會寫在這個data中  以及它的長度
         @param      dataOut         Result is written here. Allocated by caller. Encryption and decryption can be performed "in-place",
                                     with the same buffer   used for input and output.
         @param      dataOutAvailable The size of the dataOut buffer in bytes.
         //
         @param      dataOutMoved    On successful return, the number of bytes written to dataOut.
                                     If kCCBufferTooSmall is returned as a result of insufficient  buffer
                                     space being provided, the required buffer space is returned here.
         //幾種錯誤情況的說明
         @result     kCCBufferTooSmall      indicates insufficent space in the dataOut buffer.(表明dataOut的空間不足) In this case, the *dataOutMoved
                                            parameter will indicate the size of the buffer needed to complete the operation.
                                            The operation can be retried with minimal runtime penalty.
                     kCCAlignmentError      indicates that dataInLength was not properly
                                            aligned. This can only be returned for block
                                            ciphers, and then only when decrypting or when
                                            encrypting with block with padding disabled.
                     kCCDecodeError         Indicates improperly formatted ciphertext or a "wrong key" error; occurs only during decrypt operations.
         
         我們可以通過下面的解釋解讀一下這個result、具體的結果可以看下面的解釋
         @enum       CCCryptorStatus
         @abstract   Return values from CommonCryptor operations.
         enum {
                     kCCSuccess          Operation completed normally.
                     kCCParamError       Illegal parameter value.
                     kCCBufferTooSmall   Insufficent buffer provided for specified operation.
                     kCCMemoryFailure    Memory allocation failure.
                     kCCAlignmentError   Input size was not aligned properly.
                     kCCDecodeError      Input data did not decode or decrypt properly.
                     kCCUnimplemented    Function not implemented for the current algorithm.
         }
         */

 

AES加密代碼


 

      

      我們給出的就是具體的AES加密方式的代碼,涉及到的其他的Base64編碼方式等等這些我們就不在專門去寫代碼,這個在Demo中都有,需要的建議去翻翻Demo:

- (NSData *)aes256_encrypt:(NSString *)key   //加密
{
    // kCCKeySizeAES256是加密位數
    /*
     enum {
     kCCKeySizeAES128          = 16,
     kCCKeySizeAES192          = 24,
     kCCKeySizeAES256          = 32,
     kCCKeySizeDES             = 8,
     kCCKeySize3DES            = 24,
     kCCKeySizeMinCAST         = 5,
     kCCKeySizeMaxCAST         = 16,
     kCCKeySizeMinRC4          = 1,
     kCCKeySizeMaxRC4          = 512,
     kCCKeySizeMinRC2          = 1,
     kCCKeySizeMaxRC2          = 128,
     kCCKeySizeMinBlowfish     = 8,
     kCCKeySizeMaxBlowfish     = 56,
     };
     */
    char keyPtr[kCCKeySizeAES256+1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    //IV
    NSUInteger dataLength = [self length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void * buffer = malloc(bufferSize);
    size_t numBytesEncrypted = 0;
   
    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding | kCCOptionECBMode,
                                          keyPtr, kCCBlockSizeAES128,
                                          NULL,
                                          [self bytes], dataLength,
                                          buffer, bufferSize,
                                          &numBytesEncrypted);
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
    }
    free(buffer);
    return nil;
}


-(NSData *)aes256_decrypt:(NSString *)key   //解密
{
    //key 處理
    char keyPtr[kCCKeySizeAES256+1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    /*IV
     char ivPtr[kCCBlockSizeAES128 + 1];
     bzero(ivPtr, sizeof(ivPtr));
     [iv getCString:ivPtr maxLength:sizeof(ivPtr) encoding:NSUTF8StringEncoding];
     */
        
    // 輸出對象
    NSUInteger dataLength = [self length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesDecrypted = 0;
    
    //kCCDecrypt 解密
    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128,
                                          kCCOptionPKCS7Padding | kCCOptionECBMode,
                                          keyPtr, kCCBlockSizeAES128,
                                          NULL,
                                          [self bytes], dataLength,
                                          buffer, bufferSize,
                                          &numBytesDecrypted);
    if (cryptStatus == kCCSuccess) {
        return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
    }
    free(buffer);
    return nil;
}

 

最后:

      針對Base64位的編碼方式有的第三方比如:GTMBase64

      或者是針對DES的第三方比如:SSkeychain

      這些網上文章的確比較多了,我們再總結也就沒有了什么意義。下面是我參考也是收集的一下關於加密算法的總結,提供給大家。

       1、iOS各種加密 Base64 MD5 DES AES RSA    

      2、 iOS中使用RSA加密

      3、iOS中的對稱加密算法

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM