我想在WinSms项目的MySql数据库中保存用户ID和密码。我的一位朋友告诉我,这不安全;我应加密并保存。我不知道加密。
我该怎么做?
答案 0 :(得分:4)
通常密码根本不存储在数据库中。而是存储密码的哈希值。例如,您可以查看SHA156类。
网上有很多关于如何散列密码的文章 例如Storing Passwords - done right!
答案 1 :(得分:3)
请注意,您的朋友告诉您加密它,这与在表格中存储哈希(使用加密哈希函数计算)不同。
如果您加密并存储它,如果您有密钥,则可以检索密码。
如果存储密码的安全散列,则可以通过散列字符串并比较表中的散列来判断字符串是否与密码相同。
我进行了搜索并从另一个SO问题中找到this answer,这更详细地解释了为什么你应该使用哈希(安全种类)而不是加密密码。
最后但同样重要的是,无论是加密还是安全散列,请务必使用经过公开测试的库,而不是“自己动手”。
答案 2 :(得分:2)
使用encypion时,需要为数据选择算法(加密方法)。在存储用户凭证时,通常创建并存储信息的散列而不是加密它。使用哈希而非加密的优点是哈希是不可逆的,因此原始数据无法恢复。
创建哈希的过程是:
然后,当您想要稍后验证凭据时:
salt值是每个用户唯一的值,在存储之前会附加到敏感值(如用户名和密码)。 salt与哈希一起使用的原因是使生成对数据库的暴力攻击中使用的散列值列表更加困难。
private void EncryptPassword(string userPassword)
{
//Performs hashing using SHA256 algorithum
SHA256Managed hash = new SHA256Managed();
RNGCryptoServiceProvider random = new RNGCryptoServiceProvider();
byte[] saltBytes = new byte[32]; // 32 bytes = 256-bit salt.
//Fill saltBytes with cryptographically strong random values.
random.GetBytes(saltBytes);
//Get a byte representation of the password because the hash function
//works with byte arrays.
byte[] passwordBytes = Encoding.UTF8.GetBytes(userPassword);
byte[] hashInput = new byte[passwordBytes.Length + saltBytes.Length];
//Append the contents of the passwordBytes and hashBytes arrays to create
//the input to the hash function (value to be hashed)
passwordBytes.CopyTo(hashInput, 0);
saltBytes.CopyTo(hashInput, passwordBytes.Length);
//Compute (generate) a hashed representation of the input value.
byte[] hashValue = hash.ComputeHash(hashInput);
//Hashes are often stored as strings in databases.
//Hashes should be stored using Base64 encoding.
string hashString = Convert.ToBase64String(hashValue);
string saltString = Convert.ToBase64String(saltBytes);
//store hashString and saltString in database.
}
private bool AuthenticateUser(string userName, string password)
{
SHA256 hash = new SHA256Managed();
//Convert hash and salts from Base64/
byte[] storedHash = Convert.FromBase64String("Hash Value from the database");
byte[] storedSalt = Convert.FromBase64String("Salt from Database");
//Append salt to user password and hash the result
byte[] attemptedPasswordBytes = Encoding.UTF8.GetBytes(password);
byte[] hashInput = new byte[attemptedPasswordBytes.Length + storedSalt.Length];
attemptedPasswordBytes.CopyTo(hashInput, 0);
storedSalt.CopyTo(hashInput, attemptedPasswordBytes.Length);
byte[] attemptedHash = hash.ComputeHash(hashInput);
//Check whether the password entered by the user matches the stored hash.
return attemptedHash == storedHash;
}
答案 3 :(得分:0)
一个非常简单的解决方案是使用varbinary数据类型,它将以二进制格式存储密码而对其他格式不可读。
如果您想要更高的安全性,那么您需要使用加密,前提是我的sql server本身就像128位加密那样你需要创建asyymetric键然后用它加密
答案 4 :(得分:0)
您可以使用C#正面加密用户名和密码,并将该值存储在数据库中。在检索时,您必须解密它以进行匹配。看看这个link。