1

在我当前的一个项目中,我正在使用单用户身份验证系统。我说“单用户”,因为我没有计划让同一个 Windows 帐户上的多个用户使用这项工作(仅仅是因为这不是我想要做的事情)。

当用户启动应用程序时,他们会看到一个身份验证屏幕。此验证屏幕使用图像(即单击图像中的 3 个特定点)、用户名(标准编辑框)和图像选择(允许他们选择想要使用的图像的下拉菜单)。图像选择、用户名和在图像上单击的点都必须与用户在设置密码时指定的内容相匹配。

所有 3 个结果都组合成一个字符串,然后使用该Soap.EncdDecd.EncodeString方法对其进行编码。然后使用 SHA-512 对其进行哈希处理。最后,它使用 DES 加密。然后将该值与他们设置密码时创建的值进行比较。如果匹配,则授予他们访问权限。如果不是,则拒绝访问。我计划在应用程序的其他点使用 SHA512 值(例如“主密码”,用于授权自己使用主应用程序中的各种不同模块)。

在一个示例中,初始字符串长度为 29 个字符,SOAP 编码字符串约为 40 个字符,SHA-512 字符串为 128 个字符,DES 值为 344 个字符。由于我没有使用大量字符串,因此它实际上非常快。SOAP 被用作非常基本的混淆而不是安全措施。

我担心的是第一部分(纯字符串和 SOAP)可能是弱点。基本字符串不会给他们一些他们可以输入并被授予访问权限的东西,但它会给他们“图像点击坐标”以及用户名和图像选择,这可能会允许他们访问应用程序。SOAP 字符串可以很容易地解码。

加强身份验证的第一部分以尝试避免直接从记忆中窃取值的最佳方法是什么?我是否应该担心潜在的剥削者或攻击者以这种方式读取值?

作为与同一主题直接相关的附加问题;

存储用户在初始设置期间创建的密码哈希的最佳方式是什么?

我目前正在使用一种TIniFile.SectionExists方法,因为我还没有想出更优雅的方法。这是我缺乏知识的一个领域。我需要跨会话存储密码“哈希”(因此不能选择使用内存流),但我需要确保安全性足够好,以至于任何脚本小子都不会彻底破解它。


更多的是关于我是否应该关注,以及我所做的编码、散列和加密是否真的足够。我开发的图片密码系统已经是阻止传统的“我知道你的基于文本的密码是什么所以现在我在你的系统中”攻击的一个很好的基础,但我担心从内存读取的更多技术攻击.

4

1 回答 1

5

使用 SHA-512,从哈希值中检索初始内容是不可行的(至少在 20 年的计算能力和地球电能之前)是不可行的。

我什至认为使用 DES 不是强制性的,而且会增加复杂性。当然,您可以使用如此缓慢的过程来使暴力破解或基于字典的攻击更加困难(因为它会使每次尝试都变慢)。更常见的是不使用DES,而是多次调用SHA-512(例如1000次)。在这种情况下,速度可能是你的敌人:一个快速的过程将更容易攻击。

您可以做的是在初始值中添加所谓的“盐”。请参阅此维基百科文章

“盐”可以固定在代码中,也可以存储在密码中。

那是:

Hash := SHA512(Salt+Coordinates+UserName+Password);

最后的建议:

  • 永远不要将纯初始文本存储在数据库或文件中;
  • 强制使用强密码(不是“hellodave”,由于字典很容易破解);
  • 主要的安全漏洞在椅子和键盘之间;
  • 如果你是偏执狂,在释放它之前明确地覆盖(即一个字符一个字符)痛苦的初始文本内存(它可能仍然在 RAM 中的某个地方);
  • 首先了解一些众所周知的技术:最好使用带有“ nonce ”的“ challenge ”来避免任何“ replay ”或“ main in the middle ”攻击;
  • 将密码哈希存储在 DB 甚至 INI 文件中是安全的,如果您注意拥有强大的身份验证方案(例如使用质询-响应)并保护服务器访问。

例如,这里是如何“清理”你的记忆(但它可能比这复杂得多):

 Content := Salt+Coordinates+UserName+Password;
 for i := 1 to length(Coordinates) do
   Coordinates[i] := ' ';
 for i := 1 to length(UserName) do
   UserName[i] := ' ';
 for i := 1 to length(Password) do
   Password[i] := ' ';
 Hash := SHA512(Content);
 for i := 1 to length(Content) do
   Content[i] := ' ';
 for i := 1 to 1000 do 
   Hash := SHA512(Hash);

当它涉及安全时,不要试图重新发明轮子:这是一件困难的事情,你最好依靠数学证明(如 SHA-512)和经验丰富的技术(如盐,挑战......)。

对于一些身份验证方案示例,看看我们如何为我们的客户端-服务器框架实现 RESTful 身份验证。它当然不是完美的,但它试图实施一些最佳实践。

于 2012-05-09T05:26:25.350 回答