如何将密码存储为哈希值,然后在不知道明文密码的情况下对用户进行身份验证?

时间:2015-10-17 08:32:43

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

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

该应用程序的作用是:

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

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

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

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

3 个答案:

答案 0 :(得分:4)

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

请注意,您可能不想使用SHA1,也可以阅读盐的使用情况。

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

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

答案 1 :(得分:1)

@Dip 我认为你提出的问题非常普遍,围绕它进行了大量的讨论和辩论。 我建议你先了解所使用的各种加密/解密算法及其优点/缺点。

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

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

答案 2 :(得分:1)

您应该使用以下步骤:

将密码存储在AES加密中 - >在您的应用中,检索密码并对其进行解密 - >识别面部 - >打开网站 - >然后输入用户名和解密密码 - >登录 - >其他东西......
您可以使用此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