常用加密算法:
- 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位散列值
- 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中的對稱加密算法