1. 程式人生 > >關於AES加密(下)

關於AES加密(下)

上期提供了Java中AES加密,因為在使用時,一般Java作為伺服器或者終端,可能涉及到ios作為終端,至少我遇到的場景是這樣的,所以貼上IOS端的AES加密。首先我下面的程式碼是基於NSData的Category;上程式碼吧:

NSData+AES256.h

#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonCryptor.h>
#import <CommonCrypto/CommonKeyDerivation.h>
@interface NSData (AES256)
+ (NSData *)AES256EncryptWithPlainText:(NSString *)plain;        /*加密方法,引數需要加密的內容*/
+ (NSData *)AES256DecryptWithCiphertext:(NSString *)ciphertexts; /*解密方法,引數數密文*/
@end

NSData+AES256.m
#import "NSData+AES256.h"
#define PASSWORD @"Per vallum duces Labant"

static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
const NSUInteger kAlgorithmKeySize = kCCKeySizeAES256;
const NSUInteger kPBKDFRounds = 10000;  // ~80ms on an iPhone 4

//static Byte saltBuff[] = {0,1,2,3,4,5,6,7,8,9,0xA,0xB,0xC,0xD,0xE,0xF};

static NSString *key = @"
[email protected]
}[email protected]}hS/5798DGILXURXp'o$cC%!XpOibP [email protected]*kAS; [7y&BcSSo+m*"; static Byte ivBuff[] = {0xA,1,0xB,5,4,0xF,7,9,0x17,3,1,6,8,0xC,0xD,91}; @implementation NSData (AES256) + (NSData *)AESKeyForPassword:(NSString *)password{ //Derive a key from a text password/passphrase NSMutableData *derivedKey = [NSMutableData dataWithLength:kAlgorithmKeySize]; //NSData *salt = [NSData dataWithBytes:saltBuff length:kCCKeySizeAES128]; NSData *salt = [key dataUsingEncoding:NSUTF8StringEncoding]; int result = CCKeyDerivationPBKDF(kCCPBKDF2, // algorithm演算法 password.UTF8String, // password密碼 password.length, // passwordLength密碼的長度 salt.bytes, // salt內容 salt.length, // saltLen長度 kCCPRFHmacAlgSHA1, // PRF kPBKDFRounds, // rounds迴圈次數 derivedKey.mutableBytes, // derivedKey derivedKey.length); // derivedKeyLen derive:出自 NSAssert(result == kCCSuccess, @"Unable to create AES key for spassword: %d", result); return derivedKey; } /*加密方法*/ + (NSData*)AES256EncryptWithPlainText:(NSString *)plain { NSData *plainText = [plain dataUsingEncoding:NSUTF8StringEncoding]; // 'key' should be 32 bytes for AES256, will be null-padded otherwise char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) NSUInteger dataLength = [plainText length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); bzero(buffer, sizeof(buffer)); size_t numBytesEncrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128,kCCOptionPKCS7Padding, [[NSData AESKeyForPassword:PASSWORD] bytes], kCCKeySizeAES256, ivBuff /* initialization vector (optional) */, [plainText bytes], dataLength, /* input */ buffer, bufferSize, /* output */ &numBytesEncrypted); if (cryptStatus == kCCSuccess) { NSData *encryptData = [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted]; NSLog(@"%@", [encryptData base64Encoding]); return encryptData; } free(buffer); //free the buffer; return nil; } /*解密方法*/ + (NSData *)AES256DecryptWithCiphertext:(NSString *)ciphertexts{ NSData *cipherData = [NSData dataWithBase64EncodedString:ciphertexts]; // 'key' should be 32 bytes for AES256, will be null-padded otherwise char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused) bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding) NSUInteger dataLength = [cipherData length]; size_t bufferSize = dataLength + kCCBlockSizeAES128; void *buffer = malloc(bufferSize); size_t numBytesDecrypted = 0; CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding, [[NSData AESKeyForPassword:PASSWORD] bytes], kCCKeySizeAES256, ivBuff ,/* initialization vector (optional) */ [cipherData bytes], dataLength, /* input */ buffer, bufferSize, /* output */ &numBytesDecrypted); if (cryptStatus == kCCSuccess) { NSData *encryptData = [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted]; return encryptData; } free(buffer); //free the buffer; return nil; } + (id)dataWithBase64EncodedString:(NSString *)string; { if (string == nil) [NSException raise:NSInvalidArgumentException format:nil]; if ([string length] == 0) return [NSData data]; static char *decodingTable = NULL; if (decodingTable == NULL) { decodingTable = malloc(256); if (decodingTable == NULL) return nil; memset(decodingTable, CHAR_MAX, 256); NSUInteger i; for (i = 0; i < 64; i++) decodingTable[(short)encodingTable[i]] = i; } const char *characters = [string cStringUsingEncoding:NSASCIIStringEncoding]; if (characters == NULL) // Not an ASCII string! return nil; char *bytes = malloc((([string length] + 3) / 4) * 3); if (bytes == NULL) return nil; NSUInteger length = 0; NSUInteger i = 0; while (YES) { char buffer[4]; short bufferLength; for (bufferLength = 0; bufferLength < 4; i++) { if (characters[i] == '\0') break; if (isspace(characters[i]) || characters[i] == '=') continue; buffer[bufferLength] = decodingTable[(short)characters[i]]; if (buffer[bufferLength++] == CHAR_MAX) // Illegal character! { free(bytes); return nil; } } if (bufferLength == 0) break; if (bufferLength == 1) // At least two characters are needed to produce one byte! { free(bytes); return nil; } // Decode the characters in the buffer to bytes. bytes[length++] = (buffer[0] << 2) | (buffer[1] >> 4); if (bufferLength > 2) bytes[length++] = (buffer[1] << 4) | (buffer[2] >> 2); if (bufferLength > 3) bytes[length++] = (buffer[2] << 6) | buffer[3]; } bytes = realloc(bytes, length); return [NSData dataWithBytesNoCopy:bytes length:length]; } - (NSString *)base64Encoding; { if ([self length] == 0) return @""; char *characters = malloc((([self length] + 2) / 3) * 4); if (characters == NULL) return nil; NSUInteger length = 0; NSUInteger i = 0; while (i < [self length]) { char buffer[3] = {0,0,0}; short bufferLength = 0; while (bufferLength < 3 && i < [self length]) buffer[bufferLength++] = ((char *)[self bytes])[i++]; // Encode the bytes in the buffer to four characters, including padding "=" characters if necessary. characters[length++] = encodingTable[(buffer[0] & 0xFC) >> 2]; characters[length++] = encodingTable[((buffer[0] & 0x03) << 4) | ((buffer[1] & 0xF0) >> 4)]; if (bufferLength > 1) characters[length++] = encodingTable[((buffer[1] & 0x0F) << 2) | ((buffer[2] & 0xC0) >> 6)]; else characters[length++] = '='; if (bufferLength > 2) characters[length++] = encodingTable[buffer[2] & 0x3F]; else characters[length++] = '='; } return [[[NSString alloc] initWithBytesNoCopy:characters length:length encoding:NSASCIIStringEncoding freeWhenDone:YES] autorelease]; } @end