1

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

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

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

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

据我所知,盐只是您添加到哈希中的随机文本,但我认为这不是最好的选择,所以我在想一些事情:

由于散列基于固定长度(32、64 等,取决于算法)的小写十六进制值,因此我可以使用散列中每个字符的每个 ASCII 码和加载的固定值的总和来玩列表(数组)例如:

我有:abcd

每个字母的 ASCII 码:

一个-> 97

b -> 98

c -> 99

d -> 100

然后我像这样对列表的固定值求和(长度为 32 / 64 个整数)

a -> 97 + 5 = 102 => f

b -> 98 + 2 = 100 => d

c -> 99 + 7 = 106 => j

d -> 100 + 3 = 103 => g

所以结果将是:fdje 替换了 abcd 的散列。

我不知道它有多安全,黑客确定我使用的技术有多困难,问题是结果与哈希具有相同的长度,并且更难确定盐,所以如果 FOR历史上的任何原因,黑客使用彩虹表并捕捉到可能的结果,这将是错误的。你怎么看待这件事?

谢谢...

4

3 回答 3

1

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

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

问题是,我不会以文本/纯文本形式从客户端发送密码。

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

如果您建议将哈希值从客户端传递到服务器而不是密码,那么您将得到一个密码等效哈希值,如果泄漏,它会面临许多与密码相同的风险。这也意味着客户端和服务器都必须在哈希算法上达成一致,所以你不能包含盐,这意味着你仍然在服务器数据库中存储了容易破解的无盐哈希。

在十六进制编码散列中的数字上运行固定替换密码将提供非常少量的模糊性,这只会阻止最懒惰的攻击者。我认为当有很好理解的标准安全系统可以提供更好的保证时,我认为不值得费心:HTTPS 用于连接,bcrypt( PHP 中的password_hash)用于密码存储。

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

于 2013-11-10T00:30:01.190 回答
1

一个简单的替换密码不太可能让一个坚定的黑客长时间减速。

您最大的问题是您的客户的某个人可以建立一个您为特定值生成的哈希表。输入a密码字段,捕获哈希。输入b密码字段,捕获哈希。有了这种数据,对你的方法进行逆向工程就很容易了,即使它是加盐的。

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

我还认为您误解了加盐-您没有将字符添加到散列中,而是将它们添加到要散列的值中。思考hash(password + salt)而不是仅仅hash(password)

于 2013-11-09T22:59:34.530 回答
1

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

哈希的目的是消除可以为一个密码生成哈希表/彩虹表然后用于另一个密码的可能性。鉴于您有一个固定的盐生成算法,任何攻击者都可以确定该算法并使用它来对付您。

盐应该随机生成并以纯文本形式存储在密码本身的某个地方。每个密码的盐也应该是唯一的(如果您使用适当的随机盐生成器,应该可以确保这一点)。通过这样做,您可以确保一个密码的彩虹表不能用于另一个密码。

现在已经完成并尘埃落定,我们继续解决更大的问题:使用简单的哈希算法来存储密码。


不赘述,实际情况如下:

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

为了解决这个问题,已经开发了专门的密码存储/哈希算法PBKDF#2,例如bcryptscrypt,它们是有目的地占用资源和顺序的(在某种程度上不能并行化),以阻止 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 上发帖),否则不要实现您自己的加密。

于 2013-11-10T10:42:06.470 回答