字符串加密问题

Sco*_*ard 1 delphi authentication encryption delphi-xe2

在我目前的一个项目中,我正在使用单用户身份验证系统.我说"单用户",因为我没有计划在同一个Windows帐户上为多个用户进行此项工作(仅仅因为它不是我想要做的事情).

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

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

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

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

加强认证的第一部分以试图避免从内存直接撕掉这些值的最佳方法是什么?我是否应该关注潜在的剥削者或攻击者以这种方式阅读价值观?

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

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

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


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

Arn*_*hez 5

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

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

你可能要做的是在初始值上添加一个所谓的"盐".请参阅此维基百科文章.

"salt"可以在代码中修复,也可以存储在密码中.

那是:

Hash := SHA512(Salt+Coordinates+UserName+Password);
Run Code Online (Sandbox Code Playgroud)

最后的建议:

  • 切勿将简单初始文本存储在DB或文件中;
  • 强制使用强密码(不是"hellodave",由于字典而容易破解);
  • 主要的安全弱点是椅子和键盘之间;
  • 如果你是偏执狂,在释放之前显式覆盖(即每个字符一个字符)痛苦初始文本内存(它可能仍然在RAM中的某个位置);
  • 首先要了解一些众所周知的技术:你应该更好地使用带有" nonce " 的" 挑战 "来避免任何" 重放 "或" 主要在中间 "的攻击;
  • 如果您负责拥有强大的身份验证方案(例如,使用质询 - 响应)并确保服务器访问安全,则可以安全地将密码哈希存储在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);
Run Code Online (Sandbox Code Playgroud)

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

对于某些身份验证方案示例,请查看我们如何为Client-Server框架实现RESTful身份验证.它当然不是完美的,但它试图实施一些最佳实践.