密码学:为密码创建更强的哈希值

时间:2013-11-09 22:47:26

标签: security hash passwords cryptography system

我正在开发一个基于Web和客户端应用程序的系统;客户端在PHP和Http请求的帮助下在服务器中进行所有数据库查询。 Web系统是用PHP / Mysql开发的,PC上安装的客户端应用程序是用C#开发的。

好!在一个阶段,客户端必须通过登录识别用户,这看起来像一个简单的任务,但服务器IP可以通过应用程序配置部分进行更改。考虑到这一点,任何邪恶的人都可以通过输入邪恶的服务器IP地址然后窃取密码来进行网络钓鱼,事情是,我不会以文本/普通方式从客户端发送密码。

现在我正在使用md5进行密码散列(没有盐,只有纯哈希),我只使用它来存储数据库中的密码。

读了一下后,我意识到人们不建议再使用md5,而是使用sha256或更高版本,我正在考虑迁移到更好的哈希算法并创建自己的盐。

据我所知,盐只是一个随机的文本,你添加到哈希,但我不认为这是最好的选择,所以我在想什么:

由于散列是基于小写的十六进制值,具有固定长度(32,64等等...取决于算法),我可以使用固定值的总和来玩散列的每个字符的每个ASCII代码加载到列表(数组)ex:

我有:abcd

每个字母的ASCII码:

a - > 97

b - > 98

c - > 99

d - > 100

然后我总结一个固定的列表值(长度为32/64整数),像这样

a - > 97 + 5 = 102 => ˚F

b - > 98 + 2 = 100 => d

c - > 99 + 7 = 106 => Ĵ

d - > 100 + 3 = 103 =>克

结果将是:fdje取代了abcd的散列。

我不知道它有多安全,黑客确定我使用的技术有多困难,事实是结果与哈希的长度相同,并且更难确定盐,因此,如果出于历史上的任何原因,黑客使用彩虹表并捕获可能的结果,那将是错误的。你觉得怎么样?

谢谢...

3 个答案:

答案 0 :(得分:1)

一个简单的替代密码不可能长时间地减缓已确定的黑客。

您最大的问题是,与您的客户有关的人可以建立一个您为特定值生成的哈希表。在密码字段中输入a,捕获哈希值。在密码字段中输入b,捕获哈希值。使用这种数据,即使它被腌制,也很容易对您的方法进行逆向工程。

我认为您最好的选择是使用某种公钥/私钥对,以便客户端只信任您的服务器,并且不会与其他任何内容进行通信。

我还认为你误解了salting - 你没有在哈希中添加字符,你将它们添加到你正在哈希的值。想想hash(password + salt)而不仅仅是hash(password)

答案 1 :(得分:1)

  

可以使用应用程序配置部分更改服务器IP。考虑到这一点,任何邪恶的人都可以通过输入邪恶的服务器IP地址然后窃取密码来进行网络钓鱼

这作为威胁模型没有意义。如果攻击者可以在客户端上执行代码来重新配置用户的应用程序,他们就可以在服务器附近的任何地方拦截所有击键。

  

问题是,我不会在text / plain中从客户端发送密码。

保护连接的常用方法是使用SSL,这样可以将密码从客户端发送到服务器。必要的服务器证书还将负责向客户端验证服务器(尽管这仍然无法解决受损客户端端点的问题)。如果您不想购买商业CA,则可以使用自己的CA基础架构。

如果您建议将哈希从客户端传递到服务器而不是密码,那么您将获得密码等效哈希,如果泄露,则会遇到许多与密码相同的风险。此外,这意味着客户端和服务器都必须同意散列算法,因此您不能包含salt,这意味着您仍然可以在服务器数据库中存储易于破解的未经破解的哈希值。

在十六进制编码的哈希中对数字运行固定的替换密码将提供非常少量的默默无闻,这将阻止最懒的攻击者。如果有一个易于理解的标准安全系统可以提供更好的保证,我认为值得烦恼:连接的HTTPS和密码存储的bcrypt(PHP中为password_hash)。

(如果真的需要连接到你不信任的服务器,那么有像SRP这样的PAKE算法,但这是一堆工作,留下了如何解决的问题密码首先被设置和管理,如果没有连接层加密,整个协议的其余部分都不受保护。)

答案 2 :(得分:1)

您可能会误解密码和盐腌密码的含义。 Salting密码用于“防御”彩虹表(这是预先计算的值的大表)。现在,生成彩虹表一次是黑客必须做的最昂贵的操作,并且彩虹表的整个概念是加速暴力破解哈希。

散列的要点是消除为一个密码生成散列表/彩虹表然后用于另一个密码的可能性。鉴于您拥有固定盐生成算法,任何攻击者都可以确定算法并将其用于您。

应该随机生成盐,并使用密码本身以明文形式存储。每个密码的盐也应该是唯一的(如果你使用适当的随机盐生成器,这应该是非常有用的)。通过这样做,您可以确保一个密码的彩虹表对另一个密码不可用。

现在已经完成了,我们继续讨论更大的问题:使用简单的哈希算法进行密码存储。

<小时/> 没有太多细节,现实情况如下:

GPU和其他IC(例如ASIC / FGPA)已快速 。像Message Digest 5Secure Hash Algorithm 1/2这样的简单散列算法可以以惊人的速度计算,密码可以像微波炉中的爆米花一样破解。

为了解决这个问题,我们开发了专用的密码存储/散列算法,例如PBKDF#2bcryptscrypt,这些算法是有目的的资源密集型和顺序的(如不能在某种程度上并行化,以保持GPU和ASIC不受影响。

您的帖子提到您正在使用PHP,所以让我向您介绍一下您可能选择实施的这个非常简单的解决方案。从PHP 5.5开始,存在两个关键的新功能password_hash()password_verify(),它们为您完成所有艰苦而复杂的工作。

考虑以下代码:

$pass = 'foobar';

//Generates a password hash
$hash = password_hash($pass, PASSWORD_DEFAULT);

就像那样,PHP使用推荐的(bcrypt在编写本文时)为您扫描了密码,密码哈希和安全性为您提供了密码,并将输出格式化为单个字符串进行存储。

验证给定密码是否正确:

$pass_to_verify = ...

//$hash variable retrieved from the previous password_hash() function.
if(password_verify($pass_to_verify, $hash)){
    //Password is correct
}else{
    //Password is not correct
}

使用这两个函数,您可以确保(只要PHP的人不会搞砸)您的密码可以防止暴力破解。重复一个很多人一直在说的语句:除非你完全了解密码和散列算法的整个概念,否则不要实现自己的加密(在这种情况下,你可能根本不会张贴在SO)。