以加密格式获取钥匙串密码

Get Keychain password in encrypted format

我正在开发一个 iOS 应用程序,它使用钥匙串 Security.framework 和 Apple 的 KeychainWrapper class 将用户密码安全地存储在我的应用程序中。

该应用程序允许用户创建帐户。当用户创建帐户时,应用程序需要将用户密码的加密版本发送到我的服务器(POST 请求)。

一切正常,但我遇到的问题是我可以安全地存储和检索数据,但我不知道如何检索我的数据的加密版本。

换句话说,假设用户创建了一个帐户并将密码设置为 "hello"。然后我将应用程序设置为将其安全地存储在钥匙串中。

然后iOS将其加密并存储在钥匙串中。为了这个问题,我们假设加密版本是 "h235llo".

现在,当我想将密码发送到我的服务器时,我不想发送 "hello"。我想发送 "h235llo" (加密字符串)。如何访问加密字符串?

这是我用来访问钥匙串的代码:

为了安全地将 username/password 存储到钥匙串,我这样做:

KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc] initWithIdentifier:@"UserLoginData" accessGroup:nil];
[keychain setObject:_username.text forKey:(__bridge id)kSecAttrAccount];
[keychain setObject:_password.text forKey:(__bridge id)kSecValueData];

为了从钥匙串中安全地检索 username/password,我正在这样做:

NSString *secureUser = [keychain objectForKey:(__bridge id)kSecAttrAccount];
NSString *securePass = [keychain objectForKey:(__bridge id)kSecValueData];

如有任何帮助,我们将不胜感激。

谢谢你的时间,丹。

您需要生成密码的单向哈希。那就是您存储并发送到服务器的内容。

您会要求服务器为该用户提供 SALT。

Keychain 的内部加密细节是私有的,可能会发生变化。 (它们并非 完全 私有。Apple 做了 pretty nice job of explaining them,但应用程序无法访问具体细节。)

我怀疑您对加密(经过加扰后可以恢复原始数据的数据)和散列(经过加扰后可以恢复原始数据的数据)之间的区别感到困惑丢失)。密码验证通常采用散列,而不是加密。

您需要的特定类型的散列(或加密)完全取决于您的服务器。您的服务器不可能依赖特定设备上 iOS 钥匙串的内部加密状态(如果可以的话,您也不想这样做)。所以问题是,您的服务器希望身份验证请求采用什么格式。

如果您控制了服务器,并且您只是在寻找一种无需发送明文密码即可进行身份验证的好方法,那么恭喜,您考虑得很好。但是,您想要的工具不是加密。它是一个像 PBKDF2 一样的密钥派生函数。您可以在 Renaissance.io talk starting at minute 16. Or you can start at slide 33.

中找到介绍