密码以安全的方式加密和解密。

时间:2014-12-11 06:52:39

标签: c# sql-server encryption passwords

伙计我正在c#asp.net开发一个处理钱的应用程序。对于那个应用程序,应该安全地保存数据库中的密码。为此我做了一些研究,并分别从c#中提出了两个加密和解密函数。所以我的问题是我是否应该使用这两个函数或者还有其他函数安全地在我的数据库中安全地保存密码的方法。

 private string Encrypt(string clearText)
    {
        string EncryptionKey = "MAKV2SPBNI99212";
        byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (System.IO.MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(clearBytes, 0, clearBytes.Length);
                    cs.Close();
                }
                clearText = Convert.ToBase64String(ms.ToArray());
            }
        }
        return clearText;
    }

    private string Decrypt(string cipherText)
    {
        string EncryptionKey = "MAKV2SPBNI99212";
        byte[] cipherBytes = Convert.FromBase64String(cipherText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(cipherBytes, 0, cipherBytes.Length);
                    cs.Close();
                }
                cipherText = Encoding.Unicode.GetString(ms.ToArray());
            }
        }
        return cipherText;
    }

3 个答案:

答案 0 :(得分:0)

在您的实际实现中,由于各种原因,对您的盐进行硬编码并不是一种好的做法,最常见的原因可能是恶意访问您的代码,从而危及使用此类算法加密的所有数据。 相反,你应该随机化盐并将其保存在某处,例如作为哈希字符串的一部分或在数据库中以供以后检索。

本文http://crackstation.net/hashing-security.htm中有一个salted密码散列算法的C#实现。请注意,salt是随机生成的,并保存为哈希字符串本身的一部分。

答案 1 :(得分:0)

关于您的代码,它使用Code Analisys发出警告:

  

CA2202:不要多次丢弃对象

由于使用嵌套

这是一种方法: CA2202: How to solve

如果此事感兴趣,可以看看这个: CA2202: Code review

答案 2 :(得分:-1)

通常,当您在应用中使用加密功能时,请始终考虑使用非对称算法而不是普通对称算法。您应该考虑使用基于RSA密钥对的东西而不是普通的AES。更好的方法是使用它们的组合,例如:使用AES加密纯文本,然后使用RSA加密AES密钥本身,使其成为防篡改。

但对于密码,您应该考虑使用单向加密,如MD5或SHA。这使得密码非常安全。为什么?因为SHA或MD5是单向散列方法,即:给定纯文本,您可以导出其SHA或MD5散列,但不能反过来。这里没有解密条款,因此即使您的加密密码被盗,也没有人可以对其进行任何正面或反面,而暴力破解需要数年时间才能将其分解。你应该这样做:

  • 创建用户时,请使用SHA密码并将SHA字符串保存在DB中。
  • 登录时,根据用户名或电子邮件查询记录并保存在列表中。
  • 计算用户在表单中输入的密码的SHA哈希值。
  • 将计算出的SHA哈希与您从DB返回的每条记录的密码列中的值进行匹配。
  • 如果匹配,则发现用户未通过身份验证。

这种方法还可以保护您在SQL端形成注入攻击。 这种方法的唯一缺点是没有人cna恢复旧密码。您无法告诉用户他/她的旧密码是什么。如果忘记密码'重新创建新密码并使用它所需的功能。