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
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.
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.
Đâ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
- 1. Ngăn chặn các cuộc tấn công XSS
- 2. Ngăn chặn các cuộc tấn công MITM trên máy chủ
- 3. Làm thế nào để ngăn chặn tấn công phiên tomcat?
- 4. Làm cách nào để ngăn chặn tốt nhất các cuộc tấn công CSRF trong ứng dụng GAE?
- 5. Cách tốt nhất để ngăn chặn gian lận trong ứng dụng thị trường là gì?
- 6. Cách ngăn chặn các cuộc tấn công trên trang wp-login.php của WordPress
- 7. Các phương pháp hay nhất để ngăn chặn tấn công từ chối dịch vụ ở Django
- 8. ngăn chặn cuộc tấn công XSS qua url (PHP)
- 9. Cách tốt nhất để ngăn chặn quá trình Unicorn Server chạy là gì?
- 10. Cách tốt nhất để lưu trữ/tính toán điểm số của người dùng là gì?
- 11. Ngăn chặn các cuộc tấn công Javascript và XSS
- 12. Làm cách nào để ngăn chặn các cuộc tấn công bạo lực?
- 13. Cách tốt nhất để xoay CGPoint trên lưới là gì?
- 14. Đòn tấn công cầu vồng chính xác là gì?
- 15. Thực hành tốt nhất để phát hiện các cuộc tấn công DOS (từ chối dịch vụ)?
- 16. Làm thế nào để ngăn chặn HTTPS tấn công người trung gian từ phía máy chủ?
- 17. Ngăn chặn các cuộc tấn công từ điển trên ứng dụng web
- 18. Tại sao mã hóa HTML ngăn chặn các cuộc tấn công XSS nhất định?
- 19. Cách tốt nhất để ngăn chặn các lỗi php trên máy chủ sản xuất
- 20. Làm thế nào để ngăn chặn tấn công XXE (XmlDocument in .net)
- 21. Làm thế nào để ngăn chặn tấn công CSRF trong biểu mẫu web asp.net?
- 22. Cách tốt nhất để tăng một điều tra là gì?
- 23. PHP Kiểm tra tác nhân người dùng và IP để ngăn chặn tấn công phiên
- 24. cách tốt nhất và an toàn trên Android để ngăn chặn chủ đề
- 25. Làm thế nào để ngăn chặn tấn công DoS trong các ứng dụng ASP.NET MVC?
- 26. Cách tốt nhất để triển khai API REST đăng ký cho iPhone/Android là gì?
- 27. Làm thế nào để bạn ngăn chặn các cuộc tấn công bạo lực trên các dịch vụ dữ liệu RESTful
- 28. Cách tốt nhất để tải lên và lưu trữ hình ảnh trên trang web là gì?
- 29. Trường tốt nhất để lưu trữ ngày sinh là gì?
- 30. Ngăn chặn các cuộc tấn công XSS trên toàn trang web
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
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