2012-05-09 63 views
1

在我目前的一个项目中,我使用的是单用户认证系统。我说“单用户”,因为我没有计划在同一个Windows帐户上为多个用户开展这项工作(仅仅因为它不是我想要做的事)。字符串加密问题

当用户启动应用程序时,它们会显示一个验证屏幕。此认证屏幕使用图像(即点击图像中的3个特定点),用户名(标准编辑框)和图像选项(允许用户选择要使用的图像的下拉菜单)。图像选择,用户名和点击图像上的点数必须与用户在设置密码时指定的值相匹配。

将所有3个结果合并为一个字符串,然后使用Soap.EncdDecd.EncodeString方法对其进行编码。然后使用SHA-512对其进行散列。最后,它使用DES加密。然后将此值与设置密码时创建的值进行比较。如果匹配,他们被授予访问权限。如果不是,访问被拒绝。我打算在应用程序的其他位置使用SHA512值(例如在主应用程序中使用“主密码”来授权自己使用各种不同的模块)。

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

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

什么是加强验证的第一部分以尝试避免值直接从内存中扯下来的最佳方法?我是否应该关心潜在的利用者或攻击者如何读取这些值?

作为与此相同主题直接相关的另一个问题;

什么是最好的方式来存储用户在初始设置过程中创建的密码散列?

我目前有TIniFile.SectionExists方法运行,因为我已经没有抽时间去想出一些更优雅。这是我缺乏知识的一个领域。我需要在会话中存储密码“hash”(所以使用内存流不是一种选择),但是我需要确保安全性足够好,以至于不能被任何脚本kiddie彻底破解。


它真的更关心我是否应该关心,以及我所做的编码,哈希和加密是否足够。我开发的图片密码系统已经是一个很好的基础来阻止传统的“我知道你的基于文本的密码是什么现在我在你的系统中”攻击,但我关心的是更多的技术攻击从记忆里。

+0

你的用户会恨你,你的程序仍然会被黑客入侵。两个世界中最糟糕的。 –

回答

5

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

我甚至认为使用DES并不是强制性的,并增加了复杂性。当然,你可以使用这样慢的过程来使蛮力或基于字典的攻击变得更难(因为它会使每次尝试都变得更慢)。更常见的不是使用DES,而是多次呼叫SHA-512(例如1000次)。在这种情况下,速度可以成为你的敌人:快速的过程将更容易攻击。

你可能要做的是在初始值上添加一个所谓的“盐”。见this Wikipedia article

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

即:

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

最后建议:

  • 决不存储在数据库或文件中的纯初始文本;
  • 强制使用强密码(不是“hellodave”,由于字典很容易中断);
  • 主要的安全弱点是椅子和键盘之间;
  • 如果你是偏执狂,在释放之前显式覆盖(即每个字符一个字符)痛苦的初始文本内存(它可能仍然在RAM中的某处)。
  • 首先了解一些众所周知的技术:您最好使用“challenge”和“nonce”以避免任何“replay”或“main in the middle”攻击;
  • 如果您注意拥有强大的身份验证方案(例如挑战 - 响应)并保护服务器访问权限,那么将密码哈希存储在数据库甚至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)和经验丰富的技术(如盐,挑战......)。

有关验证方案的一些示例,请参见how we implemented RESTful authentication for our Client-Server framework。这当然不是完美的,但它试图实施一些最佳实践。