哈希客户端/服务器应用程序的用户密码

seb*_*ien 6 md5 password-protection string-hashing ios

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

在IOS上创建这个"签名"的最佳解决方案是什么?我应该使用MD5还是别的什么?

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

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

谢谢你的帮助,

塞巴斯蒂安.

Hol*_*lly 19

以明文形式传输密码很糟糕,所以做任何事都是很好的第一步.如果你要付出努力,那么值得知道如何正确行事.

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

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

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

一个更好但不太常见的解决方案是在密码中添加一个已知的随机字符串(通常称为Salt),使其长(可能是64个字符).客户端和服务器必须事先知道此盐.这种解决方案既便宜又简单,如果盐泄漏则无关紧要.

密码散列还有另一个常见问题.如果恶意用户知道用户密码的哈希值,那么就像设计不良的系统知道密码本身一样好.假设我们有一个需要用户名和密码哈希的RPC函数.知道密码哈希的恶意用户即使不知道密码也可以提交密码,并可以访问系统.这个已知的密码哈希将继续有效,直到用户更改密码,密码可能是数月或数年.所需要的是一种限制密码散列有用的持续时间的方法.这是通过使用动态盐来实现的.

然后,身份验证成为一个多步骤的过程.

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

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

如果您使用这样的安全机制,那么使用MD5或SHA变体并不重要.也就是说,任何新的开发都不使用SHA256是没有意义的,除非有一个非常好的理由需要MD5.