“APP的資料安全已經牽動著我們開發者的心,簡單的MD5/Base64等已經難以滿足當下的資料安全標準,本文簡單的介紹下AES與Base64的混合加密與解密”
AES:高階加密標準(英語:Advanced Encryption Standard,縮寫:AES),在密碼學中又稱Rijndael加密法,是美國聯邦政府採用的一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。經過五年的甄選流程,高階加密標準由美國國家標準與技術研究院(NIST)於2001年11月26日釋出於FIPS PUB 197,並在2002年5月26日成為有效的標準。2006年,高階加密標準已然成為對稱金鑰加密中最流行的演算法之一。
以上是來自百度百科的解釋。
下面我將用程式碼來闡述其使用方法。
首先我們建立一個NSData的類擴充套件,命名為AES,建立完如果對的話應該是這樣的NSData+AES然後匯入如下標頭檔案
1 2 |
#import <CommonCrypto/CommonDigest.h> #import <CommonCrypto/CommonCryptor.h> |
再增加加解密的方法,方便外部檔案的呼叫,寫完.h檔案如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#import <Foundation/Foundation.h> #import <CommonCrypto/CommonDigest.h> #import <CommonCrypto/CommonCryptor.h> @interface NSData (AES) //加密 - (NSData *) AES256_Encrypt:(NSString *)key; //解密 - (NSData *) AES256_Decrypt:(NSString *)key; //追加64編碼 - (NSString *)newStringInBase64FromData; //同上64編碼 + (NSString*)base64encode:(NSString*)str; @end |
.m檔案中依次實現這幾個方法,具體如下
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 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 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
#import "NSData+AES.h" static char base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @implementation NSData (AES) //加密 - (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 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; } //追加64編碼 - (NSString *)newStringInBase64FromData { NSMutableString *dest = [[NSMutableString alloc] initWithString:@""]; unsigned char * working = (unsigned char *)[self bytes]; int srcLen = (int)[self length]; for (int i=0; i<srcLen; i += 3) { for (int nib=0; nib<4; nib++) { int byt = (nib == 0)?0:nib-1; int ix = (nib+1)*2; if (i+byt >= srcLen) break; unsigned char curr = ((working[i+byt] << (8-ix)) & 0x3F); if (i+nib < srcLen) curr |= ((working[i+nib] >> ix) & 0x3F); [dest appendFormat:@"%c", base64[curr]]; } } return dest; } + (NSString*)base64encode:(NSString*)str { if ([str length] == 0) return @""; const char *source = [str UTF8String]; int strlength = (int)strlen(source); char *characters = malloc(((strlength + 2) / 3) * 4); if (characters == NULL) return nil; NSUInteger length = 0; NSUInteger i = 0; while (i < strlength) { char buffer[3] = {0,0,0}; short bufferLength = 0; while (bufferLength < 3 && i < strlength) buffer[bufferLength++] = source[i++]; characters[length++] = base64[(buffer[0] & 0xFC) >> 2]; characters[length++] = base64[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)]; if (bufferLength > 1) characters[length++] = base64[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)]; else characters[length++] = '='; if (bufferLength > 2) characters[length++] = base64[buffer[2] & 0x3F]; else characters[length++] = '='; } NSString *g = [[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES]; return g; } @end |
AES+Base64的加密方式到此已經結束了,下面講一下單純的AES字串加密的。
和上面的基本上差不多,寫一個NSString的類擴充套件,命名為AES,建立完如果對的話應該是這樣的NSString+AES匯入如下標頭檔案
1 |
#import "NSData+AES.h" |
同樣的把加解密的方法寫在.h檔案中,寫完如下
1 2 3 4 5 6 7 8 9 10 11 12 |
#import <Foundation/Foundation.h> #import "NSData+AES.h" @interface NSString (AES) //加密 - (NSString *) AES256_Encrypt:(NSString *)key; //解密 - (NSString *) AES256_Decrypt:(NSString *)key; @end |
.m實現方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
//加密 - (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 0) { return [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding]; } return nil; } |
到此我們加密的檔案基本上都已經OK了,下面我們來簡單的的使用一下,具體如下:
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 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
#import "ViewController.h" #import "NSString+AES.h" @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. //字串加密 NSString *key = @"12345678";//Key是和後臺約定的key哦,不然無法解密.... NSString *secret = @"aes Bison base64"; NSLog(@"字串加密---%@",[secret AES256_Encrypt:key]); //字串解密 NSLog(@"字串解密---%@",[[secret AES256_Encrypt:key] AES256_Decrypt:key]); //NSData加密+base64 NSData *plain = [secret dataUsingEncoding:NSUTF8StringEncoding]; NSData *cipher = [plain AES256_Encrypt:key]; NSLog(@"NSData加密+base64++++%@",[cipher newStringInBase64FromData]); //解密 plain = [cipher AES256_Decrypt:key]; NSLog(@"NSData解密+base64++++%@", [[NSString alloc] initWithData:plain encoding:NSUTF8StringEncoding]); } @end |
執行得到列印的結果如下:
1 2 3 4 |
2016-03-30 17:31:55.686 AES_256[14242:198853] 字串加密---07815ca46d20acc3ba4e43d6930c7537496e851a36dbeac34fa30c5796089b02 2016-03-30 17:31:55.687 AES_256[14242:198853] 字串解密---aes Bison base64 2016-03-30 17:31:55.687 AES_256[14242:198853] NSData加密+base64++++B4FcpG0grMO6TkPWkwx1N0luhRo22+rDT6MMV5YImwI 2016-03-30 17:31:55.687 AES_256[14242:198853] NSData解密+base64++++aes Bison base64 |
值得注意的是Key是和後臺約定的key哦,不然無法解密….
最後留下demo下載地址
打賞支援我寫出更多好文章,謝謝!
打賞作者
打賞支援我寫出更多好文章,謝謝!
任選一種支付方式