if (![SupportUserDefaults retrieveUUID])
{
if ([SupportKeyChain isExistUUID])
{
[SupportKeyChain getKeyChainUUID];
}
else
{
//生成一个uuid的方法
CFUUIDRef uuid = CFUUIDCreate(NULL);
NSString *strUuid = (__bridge NSString*)CFUUIDCreateString(NULL, uuid);
//将该uuid保存到keychain
[SupportKeyChain setKeyChainUUID:strUuid];
CFRelease(uuid);
}
}
+ (NSString*)retrieveUUID {
NSString *strUuid = (NSString*)[SupportUserDefaults getObjectForKey:kCreateUUIDKey];
return strUuid;
}
+ (NSObject *)getObjectForKey:(NSString *)key {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *encryptedData = [defaults objectForKey:key];
NSData *decryptedData = [NSData getData:encryptedData setKey:key];
NSObject *object;
if (decryptedData == nil) {
object = nil;
}else {
object = [NSKeyedUnarchiver unarchiveObjectWithData:decryptedData];
}
return object;
}
+ (NSData*)getData:(NSData *)encryptedData setKey:(NSString *)key
{
NSData *decryptedData = [encryptedData AES256DecryptWithKey:key];
return decryptedData;
}
- (NSData *)AES256DecryptWithKey:(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, kCCKeySizeAES256,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesDecrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesDecrypted];
}
free(buffer);
return nil;
}
#import <Foundation/Foundation.h>
@interface SupportKeyChain : NSObject
+ (BOOL)isExistUUID;
+ (void)setKeyChainUUID:(NSString*)strUUID;
+ (NSString*)getKeyChainUUID;
@end
#import "SupportKeyChain.h"
#import <Security/Security.h>
#import "SupportUserDefaults.h"
@implementation SupportKeyChain
+ (BOOL)isExistUUID
{
BOOL isExistUUID = NO;
NSString* appID = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
NSMutableDictionary *query = [NSMutableDictionary dictionary];
[query setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
[query setObject:appID forKey:(__bridge id)kSecAttrAccount];
[query setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit];
[query setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes];
CFTypeRef attributesRef = NULL;
OSStatus result = SecItemCopyMatching((__bridge CFDictionaryRef)query, &attributesRef);
if (result == noErr)
{
isExistUUID = YES;
}
else
{
isExistUUID = NO;
}
return isExistUUID;
}
+ (void)setKeyChainUUID:(NSString*)strUUID
{
NSString* appID = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
NSMutableDictionary *item = [NSMutableDictionary dictionary];
[item setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
[item setObject:appID forKey:(__bridge id)kSecAttrAccount];
[item setObject:[strUUID dataUsingEncoding:NSUTF8StringEncoding] forKey:(__bridge id)kSecValueData];
OSStatus err = SecItemAdd((__bridge CFDictionaryRef)item, nil);
if (err == noErr)
{
[SupportUserDefaults saveUUID:strUUID];
}
else
{
[self deleteKeyChainUUID];
}
}
+ (NSString*)getKeyChainUUID
{
NSString *strUUID = @"";
NSString* appID = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
NSMutableDictionary *item = [NSMutableDictionary dictionary];
[item setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
[item setObject:appID forKey:(__bridge id)kSecAttrAccount];
[item setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
CFTypeRef pass = NULL;
OSStatus res = SecItemCopyMatching((__bridge CFDictionaryRef)item, &pass);
if(res == noErr )
{
NSData *data = (__bridge NSData *)pass;
strUUID = [[NSString alloc] initWithBytes:[data bytes] length:[data length] encoding:NSUTF8StringEncoding];
[SupportUserDefaults saveUUID:strUUID];
}
return strUUID;
}
+ (void)deleteKeyChainUUID
{
NSString* appID = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
NSMutableDictionary* query = [NSMutableDictionary dictionary];
[query setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass];
[query setObject:appID forKey:(__bridge id)kSecAttrAccount];
[query setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData];
OSStatus err = SecItemDelete((__bridge CFDictionaryRef)query);
if (err == noErr)
{
}
else
{
}
}
@end
+ (void)saveUUID:(NSString*)strSetUuid {
[SupportUserDefaults setObject:strSetUuid key:kCreateUUIDKey];
}
+ (void)setObject:(NSObject *)object key:(NSString *)key {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *objectData = [NSKeyedArchiver archivedDataWithRootObject:object];
NSData *encryptedData = [NSData setData:objectData setKey:key];
[defaults setObject:encryptedData forKey:key];
[defaults synchronize];
}
+ (NSData*)setData:(NSData *)data setKey:(NSString *)key
{
NSData *encryptedData = [data AES256EncryptWithKey:key];
return encryptedData;
}
- (NSData *)AES256EncryptWithKey:(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, kCCKeySizeAES256,
NULL,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}