C#密码加密

C#密码加密,c#,asp.net,encryption,C#,Asp.net,Encryption,我在网上找到了一些代码,这些代码对于我正在尝试做的事情非常有效。我需要的东西将加密密码,保存到数据库,并检索容易。下面的代码几乎完成了我要查找的所有内容 string UserName = txtUser.Text; string password = txtPass.Text; string encrKey = "keyvalue"; byte[] byteKey = { }; byte[] IV = {25,

我在网上找到了一些代码,这些代码对于我正在尝试做的事情非常有效。我需要的东西将加密密码,保存到数据库,并检索容易。下面的代码几乎完成了我要查找的所有内容

        string UserName = txtUser.Text;
        string password = txtPass.Text;

        string encrKey = "keyvalue";
        byte[] byteKey = { };
        byte[] IV = {25, 47, 60, 88, 99, 106, 125, 139};
        byteKey = Encoding.UTF8.GetBytes(encrKey.Substring(0, 8));
        DESCryptoServiceProvider des = new DESCryptoServiceProvider();
        byte[] inputArray = Encoding.UTF8.GetBytes(password);

        MemoryStream ms = new MemoryStream();
        CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(byteKey, IV), CryptoStreamMode.Write);
        cs.Write(inputArray, 0, inputArray.Length);
        cs.FlushFinalBlock();
        password = Convert.ToBase64String(ms.ToArray());

        SqlCommand cmd = new SqlCommand("INSERT INTO USers (UserName, Password) VALUES (@UserName, @Password)", myConnection);
        cmd.CommandType = CommandType.Text;

        cmd.Parameters.AddWithValue("@UserName", UserName);
        cmd.Parameters.AddWithValue("@Password", password);

        SqlDataReader rdr = cmd.ExecuteReader();
我遇到的问题是,当密码为8个字符或更长时,代码会出错。我得到这个错误:

System.Security.Cryptography.CryptographyException:指定的密钥不是此算法的有效大小。该错误是在Cryptostream行上生成的


我需要使用不同类型的密钥吗?

通常的做法不是加密数据库中的密码,而是对其进行哈希运算。
当用户尝试登录时,您获取他键入的密码,对其进行哈希运算,并与数据库中存储的哈希值进行比较

行业标准的散列算法是SHA-1,它可以在.NET中随时使用

为了获得更高的安全性,在散列中使用“Salt”

您可以在此处阅读更多信息:

尝试以下方法:

var hash = Encoding.ASCII.GetBytes(password);
var sha1 = new SHA1CryptoServiceProvider();
var sha1hash = sha1.ComputeHash(hash);
var hashedPassword = Encoding.ASCII.GetString(sha1hash);

哈希密码比加密密码好得多。您将密码的散列存储在数据库中,而不再关心普通文本密码。当用户登录时,您获取普通文本密码,对其进行散列并比较两个散列(即数据库中的一个,以及您从用户输入中散列的一个)以进行身份验证。这里的明显好处是,无论访问数据库的原因是什么,您都可以确保没有人知道原始密码(理论上)。

如果您需要实际反转加密,只需使用ProtectedData类:

如果这里的其他人是正确的,请使用下面的示例类中的盐哈希。以下内容取自“”

公共密封类密码哈希
{
常量int SaltSize=16,HashSize=20,HashIter=10000;
只读字节[]\u salt,\u hash;
公共密码哈希(字符串密码)
{
新建RNGCryptoServiceProvider().GetBytes(_salt=new byte[SaltSize]);
_hash=新的Rfc2898DeriveBytes(密码,_salt,HashIter).GetBytes(HashSize);
}
公共密码哈希(字节[]哈希字节)
{
Copy(hashBytes,0,_salt=新字节[SaltSize],0,SaltSize);
Copy(hashBytes,SaltSize,_hash=new byte[HashSize],0,HashSize);
}
公共密码哈希(字节[]salt,字节[]哈希)
{
Copy(salt,0,_salt=新字节[SaltSize],0,SaltSize);
Copy(hash,0,_hash=新字节[HashSize],0,HashSize);
}
公共字节[]ToArray()
{
byte[]hashBytes=新字节[SaltSize+HashSize];
复制(_salt,0,hashBytes,0,SaltSize);
Copy(_hash,0,hashBytes,SaltSize,HashSize);
返回hashBytes;
}
公共字节[]Salt{get{return(字节[])_Salt.Clone();}
公共字节[]哈希{get{return(字节[])_Hash.Clone();}
公共bool验证(字符串密码)
{
字节[]测试=新的Rfc2898DeriveBytes(密码,_salt,HashIter).GetBytes(HashSize);
for(int i=0;i
我建议您使用bcrypt。源代码可在 下载并使用它。但是在使用它之前。阅读文档,了解它是如何工作的以及为什么bcrypt。。。 这很重要

通过我几周的关于密码加密的研究。我终于找到了最适合我需要的bcrypt。(我认为这是最适合的密码,如果我错了请更正)

这是一种单向加密。就像少数毒品程序员所说的,散列并比较,但不解密

希望这对你有帮助。如果你发现其他有趣的事情,请让我知道XD和平~~


如果我说错了,请更正XD

我尝试了MD5,并使其工作正常,但我不知道如何将数据库中的哈希与登录表单和忘记密码链接进行比较。当您对密码进行哈希运算时,您不能使用“忘记密码”向用户发送其当前密码,而是提供“重置我的密码”.SHA1比MD5好,因为MD5不再被认为是足够安全的。我可以做到。我的最后一个问题是,如何将登录表单文本框中的纯文本密码与数据库中的散列密码进行比较?当用户尝试登录时,使用与初始密码完全相同的散列算法对其键入的密码进行散列,并比较散列结果。-1使用ASCII是一个糟糕的主意。这意味着任何超出ASCII范围的字符都将被忽略!因此,两个完全不同的密码(仅由非ASCII字符组成)将具有相同的哈希!可能重复的
public sealed class PasswordHash
{
    const int SaltSize = 16, HashSize = 20, HashIter = 10000;
    readonly byte[] _salt, _hash;
    public PasswordHash(string password)
    {
        new RNGCryptoServiceProvider().GetBytes(_salt = new byte[SaltSize]);
        _hash = new Rfc2898DeriveBytes(password, _salt, HashIter).GetBytes(HashSize);
    }
    public PasswordHash(byte[] hashBytes)
    {
        Array.Copy(hashBytes, 0, _salt = new byte[SaltSize], 0, SaltSize);
        Array.Copy(hashBytes, SaltSize, _hash = new byte[HashSize], 0, HashSize);
    }
    public PasswordHash(byte[] salt, byte[] hash)
    {
        Array.Copy(salt, 0, _salt = new byte[SaltSize], 0, SaltSize);
        Array.Copy(hash, 0, _hash = new byte[HashSize], 0, HashSize);
    }
    public byte[] ToArray()
    {
        byte[] hashBytes = new byte[SaltSize + HashSize];
        Array.Copy(_salt, 0, hashBytes, 0, SaltSize);
        Array.Copy(_hash, 0, hashBytes, SaltSize, HashSize);
        return hashBytes;
    }
    public byte[] Salt { get { return (byte[])_salt.Clone(); } }
    public byte[] Hash { get { return (byte[])_hash.Clone(); } }
    public bool Verify(string password)
    {
        byte[] test = new Rfc2898DeriveBytes(password, _salt, HashIter).GetBytes(HashSize);
        for (int i = 0; i < HashSize; i++)
            if (test[i] != _hash[i])
                return false;
        return true;
    }
}