iOS開發_AES加密和解密算法的實現

高級加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。 iOS開發之Objective-c的AES加密和解密算法的實現git

#####Rijndael密碼的設計力求知足如下3條標準: 1. 抵抗全部已知的攻擊。 2. 在多個平臺上速度快,編碼緊湊。 3. 設計簡單。github

當前的大多數分組密碼,其輪函數是Feistel結構。Rijndael沒有這種結構。 算法

1.NSData加密

NSData+AES256.h中
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>

@interface NSData (AES256)


-(NSData *) aes256_encrypt:(NSString *)key;
-(NSData *) aes256_decrypt:(NSString *)key;

@end
複製代碼
NSData+AES256.m中
#import "NSData+AES256.h"

@implementation NSData (AES256)

// 加密
- (NSData *)aes256_encrypt:(NSString *)key{
    
    char keyPtr[kCCKeySizeAES256 + 1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    
    NSUInteger dataLength = [self length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesEncrypted = 0;
    
//    CCCryptorStatus cryptStatus1 = CCCrypt(<#CCOperation op#>, <#CCAlgorithm alg#>, <#CCOptions options#>, <#const void *key#>, <#size_t keyLength#>, <#const void *iv#>, <#const void *dataIn#>, <#size_t dataInLength#>, <#void *dataOut#>, <#size_t dataOutAvailable#>, <#size_t *dataOutMoved#>)
    
    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{
    
    char keyPtr[kCCKeySizeAES256+1];
    bzero(keyPtr, sizeof(keyPtr));
    [key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
    NSUInteger dataLength = [self length];
    size_t bufferSize = dataLength + kCCBlockSizeAES128;
    void *buffer = malloc(bufferSize);
    size_t numBytesDecrypted = 0;
    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;
}

@end
複製代碼

2.NSString加密

NSString+AES256.h中
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>

#import "NSData+AES256.h"

@interface NSString (AES256)

-(NSString *) aes256_encrypt:(NSString *)key;
-(NSString *) aes256_decrypt:(NSString *)key;

@end
複製代碼
NSString+AES256.m中
#import "NSString+AES256.h"

@implementation NSString (AES256)


// 加密
- (NSString *) aes256_encrypt:(NSString *)key{
    
    const char *cstr = [self cStringUsingEncoding:NSUTF8StringEncoding];
    NSData *data = [NSData dataWithBytes:cstr length:self.length];
    //對數據進行加密
    NSData *result = [data aes256_encrypt:key];
    
    //轉換爲2進制字符串
    if (result && result.length > 0) {
        
        Byte *datas = (Byte*)[result bytes];
        NSMutableString *output = [NSMutableString stringWithCapacity:result.length * 2];
        for(int i = 0; i < result.length; i++){
            [output appendFormat:@"%02x", datas[i]];
        }
        return output;
    }
    return nil;
}


// 解密
-(NSString *) aes256_decrypt:(NSString *)key{
    
    //轉換爲2進制Data
    NSMutableData *data = [NSMutableData dataWithCapacity:self.length / 2];
    unsigned char whole_byte;
    char byte_chars[3] = {'\0','\0','\0'};
    int i;
    for (i=0; i < [self length] / 2; i++) {
        byte_chars[0] = [self characterAtIndex:i*2];
        byte_chars[1] = [self characterAtIndex:i*2+1];
        whole_byte = strtol(byte_chars, NULL, 16);
        [data appendBytes:&whole_byte length:1];
    }
    
    //對數據進行解密
    NSData* result = [data aes256_decrypt:key];
    if (result && result.length > 0) {
        
        return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
    }
    return nil;
}

@end
複製代碼

3.加密、解密的使用

NSString *userName = @"userName:Coder_Sun";
NSLog(@"加密前的字符串:%@",userName);


NSString *string = [userName aes256_encrypt:@"Coder"];
NSLog(@"加密後的字符串:%@",string);
NSLog(@"%lu",(unsigned long)string.length); // 打印加密後的字符串的位數


NSString *string1 = [string aes256_decrypt:@"Coder"];
NSLog(@"解密後的字符串:%@",string1);
複製代碼

上述代碼打印結果

代碼已經上傳至git:
--> 傳送門:https://github.com/272095249/AES.git

#補充: #####加密算法原理: AES算法基於排列和置換運算。排列是對數據從新進行安排,置換是將一個數據單元替換爲另外一個。AES 使用幾種不一樣的方法來執行排列和置換運算。 AES是一個迭代的、對稱密鑰分組的密碼,它能夠使用12八、192 和 256 位密鑰,而且用 128 位(16字節)分組加密和解密數據。與公共密鑰密碼使用密鑰對不一樣,對稱密鑰密碼使用相同的密鑰加密和解密數據。經過分組密碼返回的加密數據的位數與輸入數據相同安全

加密模式:

| 加密模式 | 優勢 | 缺點 | | ------------- |::-------------:|: -------------:| | ECB模式 | app

  1. 簡單
  2. 有利於並行計算
  3. 偏差不會被傳送
|
  1. 不能隱藏明文的模式
  2. 可能對明文進行主動攻擊
| | CBC模式 |
  1. 不容易主動攻擊,安全性好於ECB,適合傳輸長度長的報文,是SSL、IPSec的標準
    1. |
      1. 不利於並行計算
      2. 偏差傳遞
      3. 須要初始化向量IV
      | | CFB模式 |
      1. 隱藏了明文模式
      2. 分組密碼轉化爲流模式
      3. 能夠及時加密傳送小於分組的數據
      |
      1. 不利於並行計算
      2. 偏差傳送:一個明文單元損壞影響多個單元
      3. 惟一的IV
      4. | | ofb模式 |
        1. 隱藏了明文模式
        2. 分組密碼轉化爲流模式
        3. 能夠及時加密傳送小於分組的數據
        |
        1. 不利於並行計算
        2. 對明文的主動攻擊是可能的
        3. 偏差傳送:一個明文單元損壞影響多個單元
        |
相關文章
相關標籤/搜索