ios - 客户端/服务器应用程序的散列用户密码

标签 ios md5 password-protection string-hashing

我有一个与网络服务器通信的 iPhone 应用程序。启动应用程序时,用户必须使用用户名和密码进行身份验证。 应用程序和 Web 服务器之间的通信是安全的 (HTTPS),但我不想向 Web 服务器发送明文密码,我只想发送密码的“签名”(签名将存储在Web 服务器上的数据库)。

在 IOS 上创建此“签名”的最佳解决方案是什么?我应该使用 MD5 还是其他什么?

我是否需要获取外部库来构建此签名,还是可以使用 IOS SDK 中的 SecKeyEncrypt 来完成?

从长远来看,我将有一个在 Android 上运行的应用程序,我必须能够为 IOS 和 Android 生成相同的签名。

谢谢你的帮助,

塞巴斯蒂安。

最佳答案

以明文形式传输密码是不好的,所以做任何事情都是好的第一步。如果您要付出努力,那么了解如何正确完成它是值得的。

虽然 MD5 不再是强大的哈希算法,但在 MD5 和 SHA256(甚至 SHA512)之间进行选择并不重要,重要的是如何使用它。让我们忽略散列算法的细节,先看看如何使用它。

使用散列的思想是字符串的散列总是相同的,并且是一种单向操作。通过捕获字符串,不可能(或不切实际)确定密码。近年来,随着彩虹表的大量使用,这已经变得不真实了。彩虹表包含每个可能的密码(最多给定长度)及其散列,以便攻击者可以使用反向查找来发现密码。彩虹表可用于 16 个字符以下密码的所有哈希算法。

这个问题有几个常见的解决方案。一种是多次(大约 1,000 次)执行散列。客户端和服务器必须知道并预先确定确切的次数,以便它们可以执行相同的操作。这具有使散列生成变得昂贵的优点和缺点。攻击者进行暴力破解在计算上变得更加困难,但如果彩虹表扩展到足够大,它们仍然有用。

更好但不太常见的解决方案是将已知的随机字符串(通常称为 Salt)添加到密码中以使其变长(可能为 64 个字符)。客户端和服务器必须事先知道此盐。这种解决方案既便宜又容易,即使盐漏了也没关系。

密码散列还有另一个常见问题。如果恶意用户知道用户密码的散列值,那么对于设计不当的系统而言,这与知道密码本身一样好。假设我们有一个需要用户名和密码哈希的 RPC 函数。知道密码哈希的恶意用户可以提交它,甚至不知道密码,并获得对系统的访问权限。这个已知的密码哈希将继续工作,直到用户更改他们的密码,这可能是几个月或几年。需要的是一种限制密码散列有用时间的方法。这是通过使用动态盐来实现的。

然后身份验证变成一个多步骤过程。

  1. 客户端连接到服务器并提供某种客户端(或设备)标识符,例如 UUID。
  2. 服务器然后为该客户端标识符生成一个动态盐。动态盐仅在短时间内有效(通常为几分钟到几小时)。
  3. 服务器将动态盐、其过期时间和关联的客户端标识符存储在数据库表中以供将来使用。
  4. 服务器将动态盐及其过期时间返回给客户端。
  5. 客户端使用上述两种机制之一对密码进行哈希处理,连接动态加盐,再次进行哈希处理,然后尝试使用用户名、客户端标识符和动态加盐哈希进行身份验证。
  6. 服务器通过检查用户已知的密码散列与提交的值来验证提交的凭据,尝试连接和散列该客户端标识符的每个已知动态盐。如果找到匹配项,则接受身份验证。

这是(大致)MySQL 使用的机制。它足够安全,可以在没有 SSL 的情况下安全使用,但我始终建议使用 SSL,以便保护其余的有效负载。

如果您使用这样的安全机制,那么使用 MD5 或 SHA 变体都没有多大关系。也就是说,任何新开发都不使用 SHA256 是没有意义的,除非有充分的理由需要 MD5。

关于ios - 客户端/服务器应用程序的散列用户密码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19436345/

相关文章:

ios - 我希望我的文本在空白处延伸

xml - 使用 MD5/SHA1 比较 XML 实例

php - 登录时页面显示为空白

JAVA Md5 返回非确定性结果

authentication - Symfony 2.1 错误凭据仅在编码密码时

ios - 用于 2D 游戏的 Unity

iOS 访问照片的权限在设备上不起作用

iphone - 找不到 com.xyz.profile.mdm 的身份证书?

excel - 限制对 Excel 工作表的查看访问

JavaScript 无法在 IE 浏览器中运行,但在 Firefox 或 Chrome 中运行良好