2009-08-08 30 views
10

Xin lỗi vì vẻ hiển nhiên của câu hỏi này, nhưng vì lý do nào đó tôi không thể tìm thấy câu trả lời dứt khoát trong tài liệu của Apple về vị trí và cách cài đặt .bundle thông tin mật khẩu được lưu trữ. Câu hỏi của tôi: nếu tôi cần lưu trữ một số thông tin đăng nhập cho ứng dụng và tôi sử dụng Settings.bundle để mật khẩu được nhập vào trường văn bản PSTextFieldSpecifier trong khu vực Cài đặt của Apple với IsSecure = YES, sau đó tôi truy cập giá trị từ ứng dụng của tôi bằng CFPreferencesCopyAppValue, không bao giờ viết nó ra NSUserDefaults và chỉ gửi nó qua mạng một cách an toàn, phương thức lưu trữ và truy xuất an toàn như thế nào khi so sánh với lưu trữ và lấy lại mật khẩu bằng cách sử dụng keychain trong cài đặt ứng dụng của riêng tôi? Cảm ơn vì đầu vào của bạn.Các tác động bảo mật của việc lưu trữ mật khẩu trong Settings.bundle và nhận được với CFPreferencesCopyAppValue

+0

Nên cất giữ băm thay cho mật khẩu. Xem câu trả lời của tôi dưới đây. – memmons

+0

Cảm ơn những gợi ý tốt - như tôi đã đề cập tại thời điểm tôi hỏi điều này một vài năm trước, tôi chỉ bị mắc kẹt với việc sử dụng keychain. – Halle

+0

Đúng. Đó là một lựa chọn tốt và Apple đã chắc chắn cải thiện nó kể từ lần đầu tiên bạn hỏi. – memmons

Trả lời

8

CFPreferencesCopyAppValue chỉ là cách tiếp cận cơ bản của Core Foundation khi bạn sử dụng NSUserDefaults. Về mặt bảo mật, các tính năng chính xác giống nhau. Nghĩa là, nó không được mã hóa. Nó chỉ an toàn theo nghĩa là nó bị che khuất. Câu trả lời "đúng" là sử dụng móc khóa.

Bộ đếm là nhiều ứng dụng sử dụng NSUserDefaults để lưu mật khẩu. Bạn có thể lập luận rằng trừ khi mật khẩu kiểm soát truy cập thông tin của bất kỳ giá trị nào thì nó không đáng để cố gắng sử dụng keychain. Điều này đưa tôi đến đối số thứ hai có lợi cho việc sử dụng một lĩnh vực an toàn trong ứng dụng Cài đặt: API khóa là ghê tởm và, ít nhất là trong kinh nghiệm của tôi, viết mã không có lỗi là khó khăn.

+0

Điều cần biết, cảm ơn. Tôi sẽ gắn bó với Keychain - không rõ ràng với tôi rằng thông tin Cài đặt đã kết thúc ở cùng một nơi với NSUserDefaults. – Halle

+2

Bạn có thể quan tâm đến việc sử dụng SFHFKeychainUtils: http://github.com/ldandersen/scifihifi-iphone/tree/d4298f123a06a91acbe8422ddb6164be3dbcff9e/security. Tôi đang sử dụng nó để lưu trữ mật khẩu và nó thực sự đơn giản hóa việc sử dụng keychain. –

+1

Tôi đã tìm thấy mã mẫu Apple có triển khai trình bao bọc keychain cho Dịch vụ Keychain khá dễ làm theo (và sau đó sử dụng trình bao bọc để quản lý chuỗi ứng dụng của riêng bạn) nếu bạn loại bỏ mã trình bày khỏi chế độ xem bộ điều khiển, mà tôi nghĩ là phần lớn sự nhầm lẫn đi kèm với ví dụ đó. – Halle

3

Keychain trên iPhone sẽ an toàn nhất, trừ khi bạn đang sử dụng mã hóa tùy chỉnh, rất khó thực hiện (và xuất). NSUserDefaults không được coi là an toàn.

8

Không lưu mật khẩu của người dùng trong gói cài đặt.
Nó không an toàn.

Hãy nhớ rằng, bạn không cần biết mật khẩu ban đầu là gì, bạn cần biết mật khẩu người dùng nhập có khớp với mật khẩu ban đầu hay không. Các cách chính xác để đối phó với mật khẩu trong iOS là một trong hai

  • Sử dụng keychain, như những người khác đã đề cập
  • Tạo một hàm băm một chiều mật mã bằng SHA-512 hoặc mã hóa khác và lưu trữ các hash kết quả và muối trong NSUserDefaults

Trong số các tùy chọn này, việc mã hóa mật khẩu và lưu trữ hàm băm + muối là dễ dàng nhất. Dưới đây là những gì bạn làm để lưu trữ các mật khẩu:

  1. Grab mật khẩu từ người sử dụng
  2. Tạo một giá trị muối ngẫu nhiên
  3. Tạo một hash về phía trước chỉ sử dụng SHA-512 và giá trị muối ngẫu nhiên
  4. Lưu trữ giá trị băm và muối kết quả trong NSUserDefaults - các tin tặc này không thể được sử dụng bởi tin tặc để xác định mật khẩu ban đầu, do đó không cần lưu trữ chúng ở một nơi an toàn.

Bây giờ, khi người dùng nhập vào mật khẩu của họ và bạn phải kiểm tra xem nó là chính xác, đây là những gì bạn cần làm:

  1. Grab mật khẩu từ người sử dụng
  2. Grab băm đã lưu trước đó + muối giá trị từ NSUserDefaults
  3. Tạo hàm băm chỉ sử dụng cùng hàm băm một chiều mà bạn đã sử dụng để mã hóa mật khẩu ban đầu - chuyển mật khẩu đã thử và giá trị muối từ NSUserDefaults
  4. So sánh băm kết quả với mã băm được lưu trữ trong NSUSerDefaults. Nếu chúng giống nhau, thì người dùng đã nhập đúng mật khẩu.

Dưới đây là đoạn code để tạo ra muối và băm phía trước chỉ:

NSString *FZARandomSalt(void) { 
    uint8_t bytes[16] = {0}; 
    int status = SecRandomCopyBytes(kSecRandomDefault, 16, bytes); 
    if (status == -1) { 
     NSLog(@"Error using randomization services: %s", strerror(errno)); 
     return nil; 
    } 
    NSString *salt = [NSString stringWithFormat: @"%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x%2x", 
         bytes[0], bytes[1], bytes[2], bytes[3], 
         bytes[4], bytes[5], bytes[6], bytes[7], 
         bytes[8], bytes[9], bytes[10], bytes[11], 
         bytes[12], bytes[13], bytes[14], bytes[15]]; 
    return salt; 
} 

NSData *FZAHashPassword(NSString *password, NSString *salt) { 
    NSCParameterAssert([salt length] >= 32); 
    uint8_t hashBuffer[64] = {0}; 
    NSString *saltedPassword = [[salt substringToIndex: 32] stringByAppendingString: password]; 
    const char *passwordBytes = [saltedPassword cStringUsingEncoding: NSUTF8StringEncoding]; 
    NSUInteger length = [saltedPassword lengthOfBytesUsingEncoding: NSUTF8StringEncoding]; 
    CC_SHA512(passwordBytes, length, hashBuffer); 
    for (NSInteger i = 0; i < 4999; i++) { 
     CC_SHA512(hashBuffer, 64, hashBuffer); 
    } 
    return [NSData dataWithBytes: hashBuffer length: 64]; 
} 

Mã ví dụ này đã được tìm thấy ở đây: http://blog.securemacprogramming.com/2011/04/storing-and-testing-credentials-cocoa-touch-edition/

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