【问题标题】:How to store password as hashes and then authenticate the user without even knowing the password in plaintext?如何将密码存储为哈希,然后在不知道明文密码的情况下对用户进行身份验证?
【发布时间】:2015-10-17 08:32:42
【问题描述】:

我正在创建一个使用人脸作为密码的桌面应用程序。到目前为止,我已经能够识别人,然后根据他们的脸对他们进行身份验证。

应用程序的作用是:

如果有人注册并在网络摄像头前展示他的脸,应用程序会识别此人并自动打开网站、填写用户名和密码文本框,并自动登录与该人脸关联的帐户。因此,用户甚至不需要输入密码。

现在,主要问题是,在注册时,用户必须出示他/她的脸以及他/她的帐户用户名和密码。我将用户名和密码存储在数据库中。我希望能够以散列形式存储密码。现在,由于密码是以sha1形式存储的,所以实际密码是未知的,当用户出示他的脸时,密码由存储在数据库中的数据自动填写。如果在密码文本框中输入了散列密码,则该密码将被网站标记为“错误密码”,因为他们希望密码为明文形式。

有没有办法存储用户密码?因为以纯文本形式存储它似乎不是一个好主意。任何有权访问数据库的人都可以看到所有用户的所有密码。虽然,如果我以明文形式存储它,应用程序将正常工作,因为密码将自动填写明文!

另外,如果有办法以散列形式将密码发送到服务器并仍然获得身份验证,请告诉我。

【问题讨论】:

  • 您可以使用 AES 加密存储它。在您的应用程序中,您可以解密并使用它。
  • 服务器是你的吗?我的意思是你能修改它的代码吗?
  • 如果是人脸识别,为什么网站要使用用户名和密码?
  • @farhan 不,我发送密码的服务器不是我的。所以,我无权访问它的代码。如果我有权限,我可以更改代码以接受哈希格式的密码,然后将其与存储在数据库中的哈希值进行比较。

标签: sql-server vb.net visual-studio


【解决方案1】:

常见的模式是这样的:密码以纯文本形式发送到服务器,服务器在将其与数据库中的哈希密码进行比较之前对其进行哈希处理。

请注意,您可能不想为此使用 SHA1,并阅读盐的用法。

我只找到了一个适合vb.net的库:http://bcrypt.codeplex.com/

编辑:请查看您是否可以发送哈希值而不是真实密码,因为存储加密密码并不比纯文本密码好多少。您将密钥存储在哪里?

【讨论】:

  • en.wikipedia.org/wiki/Blowfish_(cipher)#Weakness_and_successors Blowfish 比 AES 更容易受到攻击。不过你的回答很好。 +1
  • @mevdscnee “双向”加密从何而来?密码应以 AES 加密形式存在于数据库中。要在检索后使用它,您必须对其进行解密。就是这样。您在这里排除 SHA1。
  • @FarhanAnam 对此感到抱歉.. 我误解了你。
  • 是的,存储密钥是主要的。但最好还是存储加密的密码。有人可以比应用程序中的密钥更容易地获取密码数据库。
  • @FarhanAnam 看来 OP 并没有意识到安全或道德问题。当服务器被黑客入侵时,永远不应该承担(不必要的)用户密码泄露的风险。在我的书中,这是不道德的行为。很遗憾,您的回答(和 cmets)没有反映这一点。
【解决方案2】:

您应该使用以下步骤:

在 AES Encrpytion 中存储密码 -> 在您的应用程序中,检索密码并解密 -> 识别面部 -> 打开网站 -> 然后输入用户名和解密密码 -> 登录 -> 其他东西..
您可以使用此 AES 模块进行加密和解密:

Imports System.Collections.Generic
Imports System.IO
Imports System.Linq
Imports System.Security.Cryptography
Imports System.Text
Imports System.Threading.Tasks

Public Module AES
    Public Function AES_Encrypt(bytesToBeEncrypted As Byte(), passwordBytes As Byte()) As Byte()
        Dim encryptedBytes As Byte() = Nothing

    ' Set your salt here, change it to meet your flavor:
    ' The salt bytes must be at least 8 bytes.
        Dim saltBytes As Byte() = New Byte() {1, 2, 3, 4, 5, 6, _
        7, 8}

    Using ms As New MemoryStream()
        Using AES As New RijndaelManaged()
            AES.KeySize = 256
            AES.BlockSize = 128

            Dim key = New Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000)
            AES.Key = key.GetBytes(AES.KeySize / 8)
            AES.IV = key.GetBytes(AES.BlockSize / 8)

            AES.Mode = CipherMode.CBC

            Using cs = New CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write)
                cs.Write(bytesToBeEncrypted, 0, bytesToBeEncrypted.Length)
                cs.Close()
            End Using
            encryptedBytes = ms.ToArray()
        End Using
    End Using

    Return encryptedBytes
End Function
Public Function AES_Decrypt(bytesToBeDecrypted As Byte(), passwordBytes As Byte()) As Byte()
    Dim decryptedBytes As Byte() = Nothing

    ' Set your salt here, change it to meet your flavor:
    ' The salt bytes must be at least 8 bytes.
    Dim saltBytes As Byte() = New Byte() {1, 2, 3, 4, 5, 6, _
        7, 8}

    Using ms As New MemoryStream()
        Using AES As New RijndaelManaged()
            AES.KeySize = 256
            AES.BlockSize = 128

            Dim key = New Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000)
            AES.Key = key.GetBytes(AES.KeySize / 8)
            AES.IV = key.GetBytes(AES.BlockSize / 8)

            AES.Mode = CipherMode.CBC

            Using cs = New CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write)
                cs.Write(bytesToBeDecrypted, 0, bytesToBeDecrypted.Length)
                cs.Close()
            End Using
            decryptedBytes = ms.ToArray()
        End Using
    End Using

    Return decryptedBytes
End Function
End Module

请注意,这些函数将字节数组作为其参数并返回字节数组。您可以使用System.Text.Encoding.UTF8.GetBytes("string") 从字符串中获取字节数组,使用System.Text.Encoding.UTF8.GetString(bytes) 从字节数组中获取字符串。如有必要,您可以更改UTF8

【讨论】:

  • 谢谢,您的解决方案帮了大忙。此外,我正在使用您在此处提到的相同工作流程,效果很好。
【解决方案3】:

@Dip 我认为您提出的问题是一个非常普遍的问题,并且围绕它进行了很多讨论和辩论。 我建议您首先了解使用的各种加密/解密算法以及它们的优点/缺点。

通过 google 快速搜索,我发现以下有用的链接可帮助您选择算法 Best algorithm to Encrypting / Decrypting a string & Key storage method http://homepages.uel.ac.uk/u0430614/Encryption%20index.htm

一旦您选择了适合您需求的算法,然后开始在 vb.net 中寻找实现该算法的库

【讨论】:

    猜你喜欢
    • 2020-08-17
    • 1970-01-01
    • 2014-02-15
    • 2016-06-06
    • 2015-12-17
    • 2019-10-22
    • 2021-10-23
    • 2019-05-25
    • 1970-01-01
    相关资源
    最近更新 更多