C# 使用相同的方法对相同的明文进行加密是不同的

C# 使用相同的方法对相同的明文进行加密是不同的,c#,asp.net,encryption,passwords,C#,Asp.net,Encryption,Passwords,使用下面相同的方法对相同的明文加密两次,但加密后的密文不一样。为什么 我想在将用户信息保存到数据库时加密我的密码,并使用下面的加密方法。但我想完成编辑用户功能,在输入旧密码和新密码后,根据所选的用户ID找到用户,并加密旧密码,尝试验证键入的旧密码是否与存储在数据库中的密码匹配。但是,即使我输入了正确的密码,它们也从未匹配。因此,是否有任何方法可以加密密码,并在使用相同的方法加密密码后验证它们是否相同 //encrypt the plainText public static st

使用下面相同的方法对相同的明文加密两次,但加密后的密文不一样。为什么

我想在将用户信息保存到数据库时加密我的密码,并使用下面的加密方法。但我想完成编辑用户功能,在输入旧密码和新密码后,根据所选的用户ID找到用户,并加密旧密码,尝试验证键入的旧密码是否与存储在数据库中的密码匹配。但是,即使我输入了正确的密码,它们也从未匹配。因此,是否有任何方法可以加密密码,并在使用相同的方法加密密码后验证它们是否相同

    //encrypt the plainText
    public static string Encrypt(string plainText)
    {
        if (plainText == null || plainText == "")
            throw new ArgumentNullException("plainText");
        var temp = Encoding.UTF8.GetBytes(plainText);

        byte[] encrypted = ProtectedData.Protect(temp, null, DataProtectionScope.CurrentUser);
        return Convert.ToBase64String(encrypted);
    }
基于,它看起来像是使用机器或用户特定密钥执行双向加密。这意味着,如果正在检查密钥的机器或用户与最初加密密钥的机器不同,您将得到垃圾结果。如果您只想检查密码的有效性,我建议使用单向esecure哈希算法,而不是支持解密的双向加密。StackOverflow上的其他帖子讨论了如何使用安全哈希算法()

编辑:我还没有在不同用户的不同系统上测试过这段代码,但我希望它能更普遍地工作,因为我不希望它基于机器或用户密钥

System.Security.Cryptography.SHA256Managed sha = new System.Security.Cryptography.SHA256Managed();
byte[] hashed = sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes(args[0]));
Console.WriteLine("Hash of {0}={1}", args[0], Convert.ToBase64String(hashed));
编辑2:我还想补充一点,我对密码学的理解也建议您可能应该在哈希值中包含一些“salt”。换句话说,在对密码字符串进行散列(输入和选中时)之前,在其末尾添加一些内容(如用户名),以便使用相同密码的用户不会以相同的散列值结束。例如。

基于,它看起来像是使用机器或用户特定密钥执行双向加密。这意味着,如果正在检查密钥的机器或用户与最初加密密钥的机器不同,您将得到垃圾结果。如果您只想检查密码的有效性,我建议使用单向esecure哈希算法,而不是支持解密的双向加密。StackOverflow上的其他帖子讨论了如何使用安全哈希算法()

编辑:我还没有在不同用户的不同系统上测试过这段代码,但我希望它能更普遍地工作,因为我不希望它基于机器或用户密钥

System.Security.Cryptography.SHA256Managed sha = new System.Security.Cryptography.SHA256Managed();
byte[] hashed = sha.ComputeHash(System.Text.Encoding.UTF8.GetBytes(args[0]));
Console.WriteLine("Hash of {0}={1}", args[0], Convert.ToBase64String(hashed));

编辑2:我还想补充一点,我对密码学的理解也建议您可能应该在哈希值中包含一些“salt”。换句话说,在对密码字符串进行散列(输入和选中时)之前,在其末尾添加一些内容(如用户名),以便具有相同密码的用户不会以相同的散列值结束,例如。

以下是我在控制台应用程序中创建的内容。密码将不匹配,但正如您所看到的,您可以很好地解密它们:)

类程序
{
private static string salt=“我的盐把所有的男孩都带到院子里……等等……”;
静态void Main(字符串[]参数)
{
对于(int i=0;0<20;i++)
{
string password=“猜猜我的密码!”;
字符串密码=加密(密码,salt);
字符串解密=解密(密码,salt);
控制台。写线(解密);
睡眠(500);
}
Console.ReadKey();
}
静态公共字符串加密(字符串密码、字符串salt)
{
byte[]passwordBytes=Encoding.Unicode.GetBytes(密码);
byte[]saltBytes=Encoding.Unicode.GetBytes(salt);
byte[]cipherBytes=ProtectedData.Protect(passwordBytes、saltBytes、DataProtectionScope.CurrentUser);
返回Convert.tobase64字符串(cipherBytes);
}
静态公共字符串解密(字符串密码、字符串salt)
{
字节[]cipherBytes=Convert.FromBase64String(密码);
byte[]saltBytes=Encoding.Unicode.GetBytes(salt);
byte[]passwordBytes=ProtectedData.Unprotect(cipherBytes、saltBytes、DataProtectionScope.CurrentUser);
返回Encoding.Unicode.GetString(passwordBytes);
}
}

以下是我在控制台应用程序中拼凑的一些东西。密码将不匹配,但正如您所看到的,您可以很好地解密它们:)

类程序
{
private static string salt=“我的盐把所有的男孩都带到院子里……等等……”;
静态void Main(字符串[]参数)
{
对于(int i=0;0<20;i++)
{
string password=“猜猜我的密码!”;
字符串密码=加密(密码,salt);
字符串解密=解密(密码,salt);
控制台。写线(解密);
睡眠(500);
}
Console.ReadKey();
}
静态公共字符串加密(字符串密码、字符串salt)
{
byte[]passwordBytes=Encoding.Unicode.GetBytes(密码);
byte[]saltBytes=Encoding.Unicode.GetBytes(salt);
byte[]cipherBytes=ProtectedData.Protect(passwordBytes、saltBytes、DataProtectionScope.CurrentUser);
返回Convert.tobase64字符串(cipherBytes);
}
静态公共字符串解密(字符串密码、字符串salt)
{
字节[]cipherBytes=Convert.FromBase64String(密码);
byte[]saltBytes=Encoding.Unicode.GetBytes(salt);
byte[]passwordBytes=ProtectedData.Unprotect(cipherBytes、saltBytes、DataProtectionScope.CurrentUser);
返回Encoding.Unicode.GetString(passwordBytes);
}
}

输出中的一些随机性实际上是一种错误

你有两个选择:

  • 如果您需要从密码的加密形式恢复密码(作为您需求的一部分),请使用加密,但在进行比较之前先对结果进行解密