2009-04-14 65 views
7

我需要在NSString对象中存储密码;然而,我想要某种方式来混淆它们,所以它们不能直接从内存中读取。在NSString中存储密码而不能在内存中读取

这是一个Mac OS X(10.5)应用程序,但是一个也适用于iPhone的解决方案将非常感谢。

+0

为什么你特别需要将它们存储在一个字符串中,为什么有人试图获取该内存? – 2009-04-15 07:59:29

回答

12

如果您使用钥匙串存储密码,那么您可以不用传递字符串来处理不透明钥匙串SecKeychainItemRefs,只需要在需要的地方检索明文。这也是Mac用户期望他们的密码被处理的方式。不幸的是,不知道你为什么“需要在NSString对象中存储密码”,我不知道这是真的:-)

3

在把它们放入NSString之前,难道你不能把它们放入md5吗?那么当你去测试时,md5是输入字符串,并将其与存储的内容进行比较?

+0

这不会阻止任何人阅读它们。 – Chuck 2009-04-15 02:04:03

+0

是的。但是,您将无法使用md5字符串进行身份验证或使用任何密码。 – Ronald 2009-04-15 02:06:36

+0

它会阻止他们读取密码,但允许访问不同的散列。 – 2009-04-15 07:17:25

3

在iPhone上,沙箱将阻止任何人访问您的密码。在桌面上并不那么容易。

您应该将密码存储为散列而不是明文。我相信这会在不影响功能的情况下为您提供所需的结果。你永远无法做的唯一的事情就是再次访问明文密码 - 如果你想分析它的实力或将它传递给另一项服务。一般来说,哈希不会牺牲功能。

以下代码在rawPassword中获取密码并将其SHA-1散列存储在passwordHash中。

#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]]; 

请注意,这里没有内存管理。

查看维基百科条目explanation of password hashing

intertubes上有很多相同的代码版本。

2

我认为海报是指在内存中混淆密码,所以你不能只读内存中的伊娃内容。来自谷歌的GData库有一些有用的代码,用于将实例变量中存储为NSMutableData的密码异或。

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; 
    } 
} 

您可以保存/使用XOR恢复密码(请参阅#password口令和#setUserCredentialsWithUsername:密码:在同一个文件的方法)。异或并不是高科技加密技术,但它足以阻止偶然的窥探。对于GData客户端,您可能在保留密码数据引用的应用程序中拥有长期服务/管理器对象,我认为这是一种合理的方法。