2012-02-22 32 views
6

Tôi hiện đang sử dụng NSUserDefaults, nhưng tôi đã nghe nói rằng Jailbreakers có thể dễ dàng thay đổi các giá trị này và lừa dối trên Game Center. Tôi có nên mã hóa giá trị tôi lưu trữ không? Tôi có nên sử dụng keychain thay thế không? Tôi có nên lưu trữ các giá trị trong nhị phân trong NSUserDefualts bằng cách sử dụng BOOL (có lẽ không)? Cách tốt nhất để lưu trữ một điểm cao để ngăn chặn hacking là gì, và làm thế nào nó được thực hiện?Cách tốt nhất để lưu điểm cao trên iPhone để ngăn chặn tấn công là gì?

Trả lời

3

Mọi dữ liệu mà cần phải truy cập chỉ qua mã và cần được an toàn sẽ phù hợp một cách hoàn hảo trong Keychain.

Nếu nó trở nên nhiều hơn mà chỉ là một chút dữ liệu, sau đó mã hóa nó và lưu trữ nó trong thư mục tài liệu cũng có thể thực hiện công việc. Nhưng nếu ai đó thực sự muốn, họ tháo rời ứng dụng của bạn và cố gắng tìm khóa mã hóa. Không dễ dàng nhưng có thể được thực hiện.

+0

Có không có cách nào cho một thiết bị jailbroken để truy cập keychain? Tôi có nên mã hóa dữ liệu tôi lưu trữ trong keychain bằng cách sử dụng mã hóa NSData hay nó được lưu trữ trong chuỗi khóa đủ không? – jadengeller

+0

Vâng, có thể, nhưng keychain là mục chỉ có thể truy cập bởi các ứng dụng chia sẻ cùng một định danh gói. – rckoenes

0

Bạn có thể mã hóa các giá trị sử dụng một hardcoded cặp khóa. Bạn sẽ cần lưu dữ liệu dưới dạng đối tượng NSData và bạn có thể tiếp tục sử dụng NSUserDefaults.

question này có thể bạn quan tâm.

2

Đây là mã tôi đang sử dụng, một số trong số họ được lấy từ internet

tôi đã lấy ý tưởng từ một này: https://github.com/matthiasplappert/Secure-NSUserDefaults


làm thế nào để sử dụng

trong appdelegate của bạn .m

#import "NSUserDefaults+SecureUserDefaults.h" 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    [NSUserDefaults setSecret:@"soem secret string"]; //Cracker can still read the secret string from the binary through 
    // other initialize step 
} 

khi bạn muốn sử dụng

[[NSUserDefaults standardUserDefaults] arrayForKey:@"key" defaultValue:nil]; // if the content is modified or not exist will return default value that passed in 
[[NSUserDefaults standardUserDefaults] setSecureObject:object forKey:@"key"]; 
// check more method in NSUserDefaults+SecureUserDefaults.h 

mã ở đây

NSData + Encryption_AES256.h

#import <Foundation/Foundation.h> 

@interface NSData (Encryption_AES256) 

- (NSData *)encryptedDataWithKey:(NSData *)key; 

- (NSData *)decryptedDataWithKey:(NSData *)key; 

@end 

NSData + Encryption_AES256.m

#import "NSData+Encryption_AES256.h" 
#import <CommonCrypto/CommonCryptor.h> 

// Key size is 32 bytes for AES256 
#define kKeySize kCCKeySizeAES256 

@implementation NSData (Encryption_AES256) 

- (NSData*) makeCryptedVersionWithKeyData:(const void*) keyData ofLength:(int) keyLength decrypt:(bool) decrypt 
{ 
    // Copy the key data, padding with zeroes if needed 
    char key[kKeySize]; 
    bzero(key, sizeof(key)); 
    memcpy(key, keyData, keyLength > kKeySize ? kKeySize : keyLength); 

    size_t bufferSize = [self length] + kCCBlockSizeAES128; 
    void* buffer = malloc(bufferSize); 

    size_t dataUsed; 

    CCCryptorStatus status = CCCrypt(decrypt ? kCCDecrypt : kCCEncrypt, 
            kCCAlgorithmAES128, 
            kCCOptionPKCS7Padding | kCCOptionECBMode, 
            key, kKeySize, 
            NULL, 
            [self bytes], [self length], 
            buffer, bufferSize, 
            &dataUsed); 

    switch(status) 
    { 
     case kCCSuccess: 
      return [NSData dataWithBytesNoCopy:buffer length:dataUsed]; 
     case kCCParamError: 
      NSLog(@"Error: NSDataAES256: Could not %s data: Param error", decrypt ? "decrypt" : "encrypt"); 
      break; 
     case kCCBufferTooSmall: 
      NSLog(@"Error: NSDataAES256: Could not %s data: Buffer too small", decrypt ? "decrypt" : "encrypt"); 
      break; 
     case kCCMemoryFailure: 
      NSLog(@"Error: NSDataAES256: Could not %s data: Memory failure", decrypt ? "decrypt" : "encrypt"); 
      break; 
     case kCCAlignmentError: 
      NSLog(@"Error: NSDataAES256: Could not %s data: Alignment error", decrypt ? "decrypt" : "encrypt"); 
      break; 
     case kCCDecodeError: 
      NSLog(@"Error: NSDataAES256: Could not %s data: Decode error", decrypt ? "decrypt" : "encrypt"); 
      break; 
     case kCCUnimplemented: 
      NSLog(@"Error: NSDataAES256: Could not %s data: Unimplemented", decrypt ? "decrypt" : "encrypt"); 
      break; 
     default: 
      NSLog(@"Error: NSDataAES256: Could not %s data: Unknown error", decrypt ? "decrypt" : "encrypt"); 
    } 

    free(buffer); 
    return nil; 
} 

- (NSData*)encryptedDataWithKey:(NSData *)key 
{ 
    return [self makeCryptedVersionWithKeyData:[key bytes] ofLength:[key length] decrypt:NO]; 
} 

- (NSData*)decryptedDataWithKey:(NSData *)key 
{ 
    return [self makeCryptedVersionWithKeyData:[key bytes] ofLength:[key length] decrypt:YES]; 
} 

@end 

NSUserDefaults + SecureUserDefaults.h

012.
// 
// NSUserDefaults+SecureUserDefaults.h 
// PocketMoneyExchanger 
// 
// Created by Xiliang Chen on 12-1-17. 
// Copyright (c) 2012年 Xiliang Chen. All rights reserved. 
// 

#import <Foundation/Foundation.h> 

@interface NSUserDefaults (SecureUserDefaults) 

+ (void)setSecret:(NSString *)secret; 

- (id)objectForKey:(NSString *)defaultName defaultValue:(id)value; 
- (void)setSecureObject:(id)value forKey:(NSString *)defaultName; 

- (NSString *)stringForKey:(NSString *)defaultName defaultValue:(NSString *)value; 
- (NSArray *)arrayForKey:(NSString *)defaultName defaultValue:(NSArray *)value; 
- (NSDictionary *)dictionaryForKey:(NSString *)defaultName defaultValue:(NSDictionary *)value; 
- (NSData *)dataForKey:(NSString *)defaultName defaultValue:(NSData *)value; 
- (NSArray *)stringArrayForKey:(NSString *)defaultName defaultValue:(NSArray *)value; 
- (NSInteger)integerForKey:(NSString *)defaultName defaultValue:(NSInteger)value; 
- (float)floatForKey:(NSString *)defaultName defaultValue:(float)value; 
- (double)doubleForKey:(NSString *)defaultName defaultValue:(double)value; 
- (BOOL)boolForKey:(NSString *)defaultName defaultValue:(BOOL)value; 

- (void)setSecureInteger:(NSInteger)value forKey:(NSString *)defaultName; 
- (void)setSecureFloat:(float)value forKey:(NSString *)defaultName; 
- (void)setSecureDouble:(double)value forKey:(NSString *)defaultName; 
- (void)setSecureBool:(BOOL)value forKey:(NSString *)defaultName; 

@end 

NSUserDefaults + SecureUserDefaults.m

// 
// NSUserDefaults+SecureUserDefaults.m 
// PocketMoneyExchanger 
// 
// Created by Xiliang Chen on 12-1-17. 
// Copyright (c) 2012年 Xiliang Chen. All rights reserved. 
// 

#import "NSUserDefaults+SecureUserDefaults.h" 

#import "NSData+Encryption_AES256.h" 

static NSData *secretData; 

@implementation NSUserDefaults (SecureUserDefaults) 

+ (void)setSecret:(NSString *)secret { 
    secretData = [secret dataUsingEncoding:NSUnicodeStringEncoding]; 
} 

- (id)objectForKey:(NSString *)defaultName defaultValue:(id)value { 
    id obj = [self objectForKey:defaultName]; 
    if ([obj isKindOfClass:[NSData class]]) { 
     NSData *secureData = obj; 
     NSData *data = [secureData decryptedDataWithKey:secretData]; 
     if (data) { 
      return [NSKeyedUnarchiver unarchiveObjectWithData:data]; 
     } 
    } 
    return value; 
} 

- (void)setSecureObject:(id)value forKey:(NSString *)defaultName { 
    if (value == nil || defaultName == nil) { 
     return [self setObject:value forKey:defaultName]; 
    } 
    NSData *tobesaved = [NSKeyedArchiver archivedDataWithRootObject:value]; 
    NSData *secureData = [tobesaved encryptedDataWithKey:secretData]; 
    //NSAssert(secureData != nil, @"fail to encrpty data"); 
    [self setObject:secureData forKey:defaultName]; 
} 

- (NSString *)stringForKey:(NSString *)defaultName defaultValue:(NSString *)value { 
    id obj = [self objectForKey:defaultName defaultValue:value]; 
    if ([obj isKindOfClass:[NSString class]]) { 
     return obj; 
    } 
    return value; 
} 

- (NSArray *)arrayForKey:(NSString *)defaultName defaultValue:(NSArray *)value { 
    id obj = [self objectForKey:defaultName defaultValue:value]; 
    if ([obj isKindOfClass:[NSArray class]]) { 
     return obj; 
    } 
    return value; 
} 

- (NSDictionary *)dictionaryForKey:(NSString *)defaultName defaultValue:(NSDictionary *)value { 
    id obj = [self objectForKey:defaultName defaultValue:value]; 
    if ([obj isKindOfClass:[NSDictionary class]]) { 
     return obj; 
    } 
    return value; 
} 

- (NSData *)dataForKey:(NSString *)defaultName defaultValue:(NSData *)value { 
    id obj = [self objectForKey:defaultName defaultValue:value]; 
    if ([obj isKindOfClass:[NSData class]]) { 
     return obj; 
    } 
    return value; 
} 

- (NSArray *)stringArrayForKey:(NSString *)defaultName defaultValue:(NSArray *)value { 
    id obj = [self objectForKey:defaultName defaultValue:value]; 
    if ([obj isKindOfClass:[NSArray class]]) { 
     for (id item in obj) { 
      if (![item isKindOfClass:[NSString class]]) { 
       return value; 
      } 
     } 
     return obj; 
    } 
    return value; 
} 

- (NSInteger)integerForKey:(NSString *)defaultName defaultValue:(NSInteger)value { 
    id obj = [self objectForKey:defaultName defaultValue:[NSNumber numberWithInteger:value]]; 
    if ([obj isKindOfClass:[NSNumber class]]) { 
     return [obj integerValue]; 
    } 
    return value; 
} 

- (float)floatForKey:(NSString *)defaultName defaultValue:(float)value { 
    id obj = [self objectForKey:defaultName defaultValue:[NSNumber numberWithFloat:value]]; 
    if ([obj isKindOfClass:[NSNumber class]]) { 
     return [obj floatValue]; 
    } 
    return value; 
} 

- (double)doubleForKey:(NSString *)defaultName defaultValue:(double)value { 
    id obj = [self objectForKey:defaultName defaultValue:[NSNumber numberWithDouble:value]]; 
    if ([obj isKindOfClass:[NSNumber class]]) { 
     return [obj doubleValue]; 
    } 
    return value; 

} 

- (BOOL)boolForKey:(NSString *)defaultName defaultValue:(BOOL)value { 
    id obj = [self objectForKey:defaultName defaultValue:[NSNumber numberWithBool:value]]; 
    if ([obj isKindOfClass:[NSNumber class]]) { 
     return [obj boolValue]; 
    } 
    return value; 
} 

- (void)setSecureInteger:(NSInteger)value forKey:(NSString *)defaultName { 
    [self setSecureObject:[NSNumber numberWithInteger:value] forKey:defaultName]; 
} 

- (void)setSecureFloat:(float)value forKey:(NSString *)defaultName { 
    [self setSecureObject:[NSNumber numberWithFloat:value] forKey:defaultName]; 
} 

- (void)setSecureDouble:(double)value forKey:(NSString *)defaultName { 
    [self setSecureObject:[NSNumber numberWithDouble:value] forKey:defaultName]; 
} 

- (void)setSecureBool:(BOOL)value forKey:(NSString *)defaultName { 
    [self setSecureObject:[NSNumber numberWithBool:value] forKey:defaultName]; 
} 

@end 
Các vấn đề liên quan