2012-02-22 13 views
6

Obecnie używam NSUserDefaults, ale słyszałem, że Jailbreakers mogą łatwo zmienić te wartości i oszukać w Game Center. Czy powinienem zaszyfrować wartość, którą przechowuję? Czy zamiast tego powinienem użyć keychain? Czy powinienem przechowywać wartość binarną w NSUserDefualts używając BOOL (prawdopodobnie nie)? Jaki jest najlepszy sposób przechowywania najlepszych wyników, aby zapobiec włamaniom i jak to się robi?Jaki jest najlepszy sposób na zapisywanie najlepszych wyników na telefonie iPhone, aby zapobiec atakom hakerów?

Odpowiedz

3

Wszelkie dane, które muszą być dostępne tylko za pomocą kodu i powinny być bezpieczne, idealnie pasują do urządzenia KeyChain.

Jeśli stanie się to więcej niż tylko trochę danych, można je również zaszyfrować i zapisać w katalogu dokumentów. Ale jeśli ktoś naprawdę chce, demontuje twoją aplikację i próbuje zlokalizować klucz szyfrowania. Nie jest to łatwe, ale można to zrobić.

+0

Czy nie ma sposobu na jailbroken urządzenia dostępu do pęku kluczy? Czy nadal powinienem szyfrować dane, które przechowuję w pęku kluczy za pomocą szyfrowania NSData, lub czy jest ono wystarczająco przechowywane w pęku kluczy? – jadengeller

+0

Cóż, mogą, ale pęku kluczy element jest dostępny tylko dla aplikacji, które mają ten sam identyfikator pakietu. – rckoenes

0

Można szyfrować wartości za pomocą zakodowanej pary kluczy. Będziesz musiał zapisać dane jako obiekt NSData i możesz nadal używać NSUserDefaults.

Ten numer question może Cię zainteresować.

2

Jest to kod używam, niektóre z nich zostały zaczerpnięte z internetu

wziąłem pomysł z tego: https://github.com/matthiasplappert/Secure-NSUserDefaults


jak używać

w AppDelegate .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 
} 

jeśli chcesz użyć

[[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 

kod tutaj

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

// 
// 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 
Powiązane problemy