【问题标题】:Store a Password Securely安全地存储密码
【发布时间】:2010-10-14 16:09:44
【问题描述】:

我需要“密码保护”我的应用程序,但需要有关在何处安全存储密码的建议。

我打算如何做到这一点:

程序第一次运行时,我会提示用户创建密码。密码将在 SHA-256 中加盐和散列,然后存储在注册表或文件中。

问题:

如果我将散列密码存储在注册表或文件(或两者)中,那么某人只需删除注册表或文件中的密钥并提示创建新密码就太容易了...

如何安全地存储散列密码,使其更难被删除?

我曾考虑将其存储在注册表中,并创建一个具有隐藏和系统属性的文件,以便在删除注册表文件时从中读取,但这似乎很愚蠢,因为它也可以很容易地删除。

// 我希望我已经用正确的标签正确地发布了这个问题 - 我是新来的,所以请放轻松! ;)

一切顺利

克里斯(香巴拉)

【问题讨论】:

  • 你在防御谁/什么?
  • 为什么您的用户应该能够一开始就提供密码,然后再也不会?
  • SLaks... 我需要确保除了创建密码的人之外没有人可以访问该程序。
  • codymanix... 创建密码后,用户可以登录程序并根据需要多次更改密码。我只需要想办法让密码不容易被删除。
  • @Shamballa:这是他们的责任,不是你的。如果程序在计算机本身上(不在您的服务器上运行并且通过网络连接访问),那么您无法做任何事情来阻止拥有计算机的坚定用户访问它。你可以用一些技巧让他慢一点,但就是这样。

标签: security delphi passwords


【解决方案1】:

这基本上是一个编程道德 101 问题。如果您将信息存储在其他人的计算机上,请记住计算机是他们的财产,他们有权删除或修改其上的任何文件或注册表项。试图让他们无法做到这一点是一个非常糟糕的主意。

你不能这样做是有充分理由的。如果有人开始将您无法删除或修改的文件放在您的计算机上,会发生什么?推断出合乎逻辑的结论:如果病毒开始将您无法删除或修改的文件放在您的计算机上,并且在无限循环中这样做,直到硬盘驱动器已满,会发生什么?你知道如果可能的话,有人会尝试的。

如果您想要一个程序将密码存储在用户无法修改的地方,请将其放在您的服务器上,并让您的程序通过 Internet 连接与其联系。 (这是完全不同的蠕虫罐头,但至少您不再尝试做不可能的事情或侵犯用户的基本财产权。)

【讨论】:

  • 通过互联网是一种非常安全的方式,但是您需要确保您的服务始终处于允许状态以允许他们登录,就像那里的一些游戏服务一样。如果该程序仅在可以连接到您的服务时才有效,这也将允许您在服务器上管理您的许可结构(如果有的话)。不这样做有它自己的缺点。
  • 是的。就像我说的,这带来了它自己的蠕虫罐头。但至少理论上是可行的。 OP 想要的根本不是。
  • 我认为道德问题是双向的。只要用户可以更改或删除密码首先提供现有密码,我认为您不会剥夺他们的任何权利。问题在于用户特别希望在创建密码后锁定他或她的应用程序——如何实现?
【解决方案2】:

您并没有真正指定此密码保护的内容。我假设它用于保护您的程序创建的数据。

我不是安全专家或密码学家,但如果数据存储在本地,解决方案很简单。将密码(或更可能是密码的哈希)和数据存储在同一个位置(文件、数据库等),并使用单独的密钥进行加密。

这可以防止通过文件删除来规避。他们也会删除所有数据。这将挫败除了最坚定的最终用户之外的所有用户。

【讨论】:

  • 我也打算提到这一点。使用密码作为加密密钥。这样一来,他们的数据就真的很安全了,删除密码也没有意义。唯一的问题是,很多人实际上并不希望他们的数据加密。他们希望能够在忘记密码的情况下恢复他们的数据,但他们不希望仅通过打开程序就可以轻松访问他们的数据。我知道你不能一边吃蛋糕一边吃,但这是很多用户想要的。
  • 密码是为了保护对实际程序的访问。 IE。安装后能够实际访问该程序。我正在开发的程序是一个电子邮件加密程序。它在 256 位 CBS 模式下使用 AES Rijndael,因此在加密之前选择此密码,但从未存储。我用 SHA-256 初始化他们使用的“密钥”,它成为实际的密钥。它永远不会被存储。否则问题将是任何人都可以使用单个预先确定的密钥解密数据......
【解决方案3】:

您可以使用Windows crypto API 安全地存储应用程序的密码。在CodeGuru 中有一个使用示例,但它是用 C++ 编写的,而不是 Delphi。代码难度不大,转Delphi应该比较容易。

更高级的解决方案是在下载应用程序之前询问用户密码,并嵌入二进制的哈希密码部分 - 当然,如果您获得应用程序的多个副本,您可以轻松确定加密的位置值,以及检查它以将其删除的代码。

问题是您没有从使用密码中创造任何价值,即它似乎只是一个密码。您应该使用密码作为加密应用程序数据的种子,并将密码与数据绑定。丢失密码,您只会丢失数据。

【讨论】:

    【解决方案4】:

    最好的解决方案是依靠用户无法控制的外部来源来存储密码的一部分。否则,无论你把它藏在哪里,只要有一些免费工具和一点时间,就可以很容易地发现它。

    就我个人而言,我发现存储此类数据的最佳位置是公开的,以及应用程序经常访问的其他数据。请记住,如果用户有权修改数据,则存在风险。

    如果要锁定程序,请在程序运行之前要求密钥已经存在。这样,您只需要担心如何获得密钥,而且由于它是加密的,因此他们更难创建一个适用于您的系统的密钥。

    对于您的初始身份验证过程,您可以将部分密钥放在您的网络服务器上,为用户提供创建加密文件所需的密钥。使用密钥将引导他们找到您服务器上的密钥,如果它有效,则允许他们保存加密文件。如果您担心重新激活,那么一旦激活,您可以删除网络服务器上的文件。

    另一种选择是使用 OnGuard (latest versions) 之类的东西来编码您提供给用户的限时密钥。然后在运行激活时检查您提供的密钥是否已过期,如果是,则不允许激活。这样,您的激活密钥只会在有限的时间内处于危险之中。

    不要在这上面花太多时间。即使是最好的算法也可以在应用部署后通过一些NOP 指令进行修补。

    【讨论】:

    • 这是一个不错的选择,用某种键锁释放程序。因此生成的序列号将解锁程序并允许它使用和运行,然后允许用户提供自己的密码。这比试图坚持他们使用互联网连接来验证许可证要简洁得多。这是一个共享软件入门工具包的链接,可能会给您一些想法。 blogs.msdn.com/b/danielfe/archive/2005/07/10/437293.aspx
    • @jimplode - 是的,这也有效,但不限制密钥的使用,除非有外部因素可以对抗它。
    • 是的...许可和序列保护是一项非常棘手的工作!如果是我,我不会打扰并将其瞄准专业市场,该市场会付费使用而不是滥用它。特别是因为他们都受到审计,他们不能真正作弊。私营部门......祝你好运,如果它在公众手中,无论你做什么都会被破解。
    【解决方案5】:

    至少有两种方法可以解释您的问题。

    (1) 您希望存储密码,以便以后可以使用它们登录远程数据库。

    Password encryption in Delphi 上的This answer 解释了加密部分。

    这样您可以存储密码,以便以后在用户使用数据库服务器上的应用程序或其他东西登录时,可以使用该密码对用户进行身份验证。

    “不删除”部分对用户来说非常敏感;我不会那样做。

    (2) 你想存储一个密码,所以它可以用来验证一个用户在本地访问你的应用程序。

    这个比较难,基本上你做不到。

    最接近的方法是保持后台进程运行以锁定文件。
    您与该进程通信以解锁文件,以便验证密码。

    --杰罗恩

    【讨论】:

    • 对不起 - 所以弄乱了编号;我输入了 1. 和 2.
    • ...直到用户使用进程管理器检测谁持有锁,终止进程并删除文件。 ;)
    • 这就是病毒和特洛伊木马编写者如此努力隐藏他们的东西的原因。他们不能。除非他们像 Sony 那样安装 root 工具包来保护版权:en.wikipedia.org/wiki/Sony_BMG_CD_copy_protection_scandal
    • 嗯(2)就是我需要的!我真的从没想过我会这么快就收到这么多反馈,这一切让我有点不知所措。我目前正在研究 Windows Crypto API……我不会像 Sony 那样编写 Rootkit! ;)
    • @Shamballa:请注意,“安全本地存储”也可以被检测到并从中删除信息。感谢(2)写作提示;我将 1. 和 2. 更改为 (1) 和 (2),所以现在答案看起来又好了。
    【解决方案6】:

    从你的描述来看,你不明白如果你拥有的所有安全都是

    if not SameString(Hash(UserPassword), StoredPassword) then exit;
    

    那么你就没有安全感了,这不是用户删除你的密码文件的问题。用户可以在任何二进制编辑器中打开您的 exe 文件,然后 nop 执行检查的部分:

    //if not SameString(Hash(UserPassword), StoredPassword) then exit;
    //Check commented out ---malicious user
    

    您必须意识到,即使您编译了您的应用程序,它仍然包含所有源代码,只是在汇编程序中。您仍然可以编辑源代码,只是有点困难,因为它现在使用不同的语言。

    因此,如果你想阻止用户在你的应用中做某事,只有两种方法:

    1. 对您的应用程序及其文件进行写保护。或者将它们存储在单独的服务器上,如果您无法控制这台服务器。或者只是让它们成为一个只接受一组固定命令的服务。

    2. 使应用程序不会对其进行检查,而是使用密码对关键内容进行加密。当然,恶意用户可以重置密码甚至完全删除解密程序,但他仍然需要解密数据。

    所有其他解决方案都可以被规避,不同之处在于规避所需的时间和技能。例如,您可以加密应用程序代码的关键部分并即时解密(这样做一次)。然后执行并加密回来。如果没有正确的密码,您的应用将永远无法运行。

    但恶意用户可以使用已知密码安装应用程序的单独副本,在解密时检查程序的某些部分,并将它们组装到未加密的源中。当然,这是很多工作。但它可以在有限的时间内完成。

    【讨论】:

      【解决方案7】:

      如果您只需要一个密码,请将其加密并附加在 .exe 的末尾。我已经成功完成了很多次。

      【讨论】:

      • 如果用户不是管理员或不运行提升的 exe,则可能没有写入权限。
      • 这听起来很有趣,将密码存储在程序中?这不会被防病毒程序标记为坏吗?
      • 哎呀 - 按下 并在我完成输入之前提交!我要补充>>你是怎么做到的?这需要在运行时添加。
      【解决方案8】:

      我建议在 Windows 中使用身份验证功能,特别是 CredWriteCredRead。也可以使用加密窗口提供的(CryptProtectData/CryptProtectMemory),然后保存凭据

      编辑:如果您需要 Delphi 的标头,可以在 Jedi Windows Api Library 中找到它们。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-03-23
        • 2012-05-23
        • 1970-01-01
        • 2013-06-02
        • 2018-05-13
        • 2016-04-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多