2009-04-14 34 views
7

Tôi cần lưu trữ mật khẩu trong các đối tượng NSString; tuy nhiên, tôi muốn một số cách để làm xáo trộn chúng, vì vậy chúng không thể đọc trực tiếp từ bộ nhớ.Lưu trữ mật khẩu trong NSString mà không thể đọc được trong bộ nhớ

Đây là ứng dụng Mac OS X (10.5), nhưng một giải pháp cũng hoạt động trên iPhone sẽ được nhiều người đánh giá cao.

+0

Tại sao bạn đặc biệt cần phải lưu trữ chúng trong một chuỗi và tại sao có những người cố gắng để có được ở bộ nhớ đó? –

Trả lời

12

Nếu bạn sử dụng keychain để lưu mật khẩu, thay vì truyền chuỗi xung quanh, bạn có thể xử lý móc khóa mờ SecKeychainItemRefs, chỉ truy xuất văn bản thô tại thời điểm bắt buộc. Đó cũng là cách người dùng Mac mong đợi mật khẩu của họ được xử lý. Rất tiếc, không biết lý do bạn "cần lưu trữ mật khẩu trong các đối tượng NSString" Tôi không thể biết điều đó có thực sự đúng không :-)

3

Bạn không thể chỉ md5 chúng trước khi đặt chúng trong NSString? Sau đó, khi bạn đi để kiểm tra, md5 chuỗi đầu vào và so sánh với những gì được lưu trữ?

+0

Điều đó sẽ không ngăn ai đọc chúng. – Chuck

+0

Đúng.Nhưng bạn sẽ không thể sử dụng chuỗi md5 để xác thực hoặc bất kỳ mật khẩu nào đang được sử dụng. – Ronald

+0

Nó sẽ ngăn họ đọc mật khẩu nhưng cho phép truy cập vào băm khác nhau. –

3

Trên iPhone, sandbox sẽ ngăn mọi người truy cập vào mật khẩu của bạn. trên máy tính để bàn nó không phải là dễ dàng như vậy.

Bạn nên lưu trữ mật khẩu dưới dạng băm chứ không phải cleartext. Tôi tin rằng điều này sẽ giúp bạn có được kết quả mong muốn mà không ảnh hưởng đến chức năng. Chỉ nghĩ rằng bạn sẽ không bao giờ có thể làm là truy cập lại mật khẩu cleartext - nếu bạn muốn phân tích nó cho sức mạnh hoặc chuyển nó vào một dịch vụ khác. Nói chung mặc dù, hashes sẽ không hy sinh chức năng.

Đoạn mã sau lấy mật khẩu trong rawPassword và lưu mã băm SHA-1 của nó trong mật khẩuHash.

#import <CommonCrypto/CommonDigest.h> 

const char* utf8PasswordRepresentation = [rawPassword UTF8String]; 
unsigned char * rawHash = malloc(CC_SHA1_DIGEST_LENGTH); 

CC_SHA1(utf8PasswordRepresentation, strlen(utf8PasswordRepresentation), rawHash); 

NSMutableString* passwordHash = [NSMutableString CC_SHA1_DIGEST_LENGTH*2]; 
for (int i = 0 ; i< CC_SHA1_DIGEST_LENGTH; i++) 
    [passwordHash appendFormat:@"%02x" , rawHash[i]]; 

Lưu ý rằng không có quản lý bộ nhớ tại đây.

Khám phá mục nhập wikipedia cho số explanation of password hashing.

Có nhiều phiên bản của cùng mã này xung quanh các intertubes.

+0

bạn đã bỏ lỡ stringWithCapacity: dòng 8 – nico

2

Tôi nghĩ rằng áp phích đề cập đến việc làm xáo trộn mật khẩu trong bộ nhớ, vì vậy bạn không thể chỉ đọc nội dung của ivar ra khỏi bộ nhớ. Thư viện GData từ google có một số mã hữu ích cho các mật khẩu XORing được lưu trữ dưới dạng NSMutableData trong các biến mẫu.

source for GDataServiceBase.m

// XorPlainMutableData is a simple way to keep passwords held in heap objects 
// from being visible as plain-text 
static void XorPlainMutableData(NSMutableData *mutable) { 

    // this helps avoid storing passwords on the heap in plaintext 
    const unsigned char theXORValue = 0x95; // 0x95 = 0xb10010101 

    unsigned char *dataPtr = [mutable mutableBytes]; 
    NSUInteger length = [mutable length]; 

    for (NSUInteger idx = 0; idx < length; idx++) { 
     dataPtr[idx] ^= theXORValue; 
    } 
} 

Bạn có thể lưu/khôi phục lại mật khẩu sử dụng XOR (xem #password và #setUserCredentialsWithUsername: Mật khẩu: phương pháp trong cùng một tập tin). XOR không phải là mã hóa công nghệ cao, nhưng nó đủ tốt để ngăn chặn việc rình mò thông thường. Trong trường hợp của máy khách GData, nơi bạn có thể có một đối tượng dịch vụ/người quản lý lâu đời trong một ứng dụng lưu giữ một tham chiếu đến dữ liệu mật khẩu, tôi nghĩ đây là một cách tiếp cận hợp lý.

+0

Cảm ơn Brian, ban đầu đây là những gì tôi đã đề cập đến nhưng câu trả lời của Graham Lee giải quyết tốt hơn vấn đề của tôi. Nhưng điều này cũng rất hữu ích +1 – rjstelling

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