Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 源字节数组到字符串,然后返回到字节数组与源不同_C#_Unicode - Fatal编程技术网

C# 源字节数组到字符串,然后返回到字节数组与源不同

C# 源字节数组到字符串,然后返回到字节数组与源不同,c#,unicode,C#,Unicode,我对下一段(简化的)代码感到困惑。当用户注册时,它加密密码,将哈希转换为字符串,并将其保存在数据库中。在该用户尝试登录之后,代码从数据库中读取密码,获取其字节数,并与用户输入的密码的加密哈希进行比较 static void Main(string[] args) { //User registration byte[] passwordBytes = Encoding.Unicode.GetBytes("P@ssword"); byte[] hashBytes = Get

我对下一段(简化的)代码感到困惑。当用户注册时,它加密密码,将哈希转换为字符串,并将其保存在数据库中。在该用户尝试登录之后,代码从数据库中读取密码,获取其字节数,并与用户输入的密码的加密哈希进行比较

static void Main(string[] args)
{
    //User registration
    byte[] passwordBytes = Encoding.Unicode.GetBytes("P@ssword");
    byte[] hashBytes = GetHash(passwordBytes);
    string stringFieldInDb = Encoding.Unicode.GetString(hashBytes); //password hash is being stored in database


    //Check password
    byte[] hashBytesInDb = Encoding.Unicode.GetBytes(stringFieldInDb); //was read from database

    byte[] enteredPasswordBytes = Encoding.Unicode.GetBytes("P@ssword");
    byte[] enteredPasswordHash = GetHash(enteredPasswordBytes);

    //is false
    var isPasswordValid = hashBytesInDb.SequenceEqual(enteredPasswordHash);

    //this way is true
    var isPasswordValid2 = stringFieldInDb == Encoding.Unicode.GetString(enteredPasswordHash);
}

private static byte[] GetHash(byte[] data)
{
    return new SHA512CryptoServiceProvider().ComputeHash(data);
}
哈希值略有不同,来自数据库的哈希字符串字节数:

161, 127, 0, 49, 27, 146, **253, 255**, 109, 214, **253, 255**, 113, 75, 226, ...
登录时输入的密码生成的哈希字符串字节数:

161, 127, 0, 49, 27, 146, **74, 219**, 109, 214, **65, 220**, 113, 75, 226, ...
我把上面的例子缩短为三行,我想知道这个结果的原因是什么

byte[] someCharBytes = new byte[] { 74, 219 };
string someChar = Encoding.Unicode.GetString(someCharBytes);
byte[] differentSomeCharBytes = Encoding.Unicode.GetBytes(someChar); //returns { 253, 255 }

您正在尝试将散列数据(基本上是随机字节)解释为有效的UTF-16数据。那是行不通的。并非所有字节组合都有效。您得到的特定字节是
U+FFFD替换字符
的UTF-16表示形式,该字符用于通知无效字节序列

如果需要将字节数组转换为字符串进行存储,
base64编码非常流行。查看
Convert.ToBase64String
Convert.FromBase64String

您正在尝试将哈希数据(基本上是随机字节)解释为有效的UTF-16数据。那是行不通的。并非所有字节组合都有效。您得到的特定字节是
U+FFFD替换字符
的UTF-16表示形式,该字符用于通知无效字节序列

如果需要将字节数组转换为字符串进行存储,
base64编码非常流行。查看
Convert.ToBase64String
Convert.FromBase64String

作为旁注,不要忘记添加密码。实际上,最好只使用内置的
Rfc2898DeriveBytes
类对密码进行哈希运算。看看这个:作为一个补充,别忘了给你的密码加盐。实际上,最好只使用内置的
Rfc2898DeriveBytes
类对密码进行哈希运算。看看这个: