Nat*_*ten 136 c# string hash sha256
我尝试使用SHA256散列字符串,我使用以下代码:
using System;
using System.Security.Cryptography;
using System.Text;
public class Hash
{
public static string getHashSha256(string text)
{
byte[] bytes = Encoding.Unicode.GetBytes(text);
SHA256Managed hashstring = new SHA256Managed();
byte[] hash = hashstring.ComputeHash(bytes);
string hashString = string.Empty;
foreach (byte x in hash)
{
hashString += String.Format("{0:x2}", x);
}
return hashString;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,与我的朋友php以及在线生成器(例如This generator)相比,此代码提供了显着不同的结果.
有谁知道错误是什么?不同的基地?
Quu*_*one 150
Encoding.Unicode
是微软对UTF-16的误导性名称(双宽编码,由于历史原因在Windows世界中使用但未被其他任何人使用).http://msdn.microsoft.com/en-us/library/system.text.encoding.unicode.aspx
如果你检查你的bytes
数组,你会看到每隔一个字节0x00
(由于双宽编码).
你应该使用Encoding.UTF8.GetBytes
而不是.
但是,根据您是否认为终止'\0'
字节是您正在散列的数据的一部分,您将看到不同的结果.散列这两个字节"Hi"
会产生与散列三个字节不同的结果"Hi"
.你必须决定你想做什么.(据推测,你想要做你朋友的PHP代码所做的任何事情.)
对于ASCII文本,Encoding.UTF8
肯定是合适的.如果您的目标是与朋友的代码完美兼容,即使在非ASCII输入上,您最好尝试一些非ASCII字符的测试用例,例如é
和?
,看看您的结果是否仍然匹配.如果没有,你将不得不弄清楚你的朋友正在使用什么编码; 它可能是在Unicode发明之前流行的8位"代码页"之一.(再次,我认为Windows是任何人仍然需要担心"代码页"的主要原因.)
Nic*_*dum 99
我也遇到了另一种实现方式的问题,但是我忘记了自2年前我得到它的地方.
static string sha256(string randomString)
{
var crypt = new SHA256Managed();
string hash = String.Empty;
byte[] crypto = crypt.ComputeHash(Encoding.ASCII.GetBytes(randomString));
foreach (byte theByte in crypto)
{
hash += theByte.ToString("x2");
}
return hash;
}
Run Code Online (Sandbox Code Playgroud)
当我输入类似的东西时abcdefghi2013
,它会给出不同的结果并导致我的登录模块出错.然后我试图修改代码由Quuxplusone建议,改变了从编码以同样的方式ASCII
来UTF8
那么它终于成功了!
static string sha256(string randomString)
{
var crypt = new System.Security.Cryptography.SHA256Managed();
var hash = new System.Text.StringBuilder();
byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(randomString));
foreach (byte theByte in crypto)
{
hash.Append(theByte.ToString("x2"));
}
return hash.ToString();
}
Run Code Online (Sandbox Code Playgroud)
再次感谢Quuxplusone的精彩和详细解答!:)
Ami*_*adi 19
如果您使用 .NET 5 或更高版本,现在只需3 行代码即可实现此目的。
\nstring QuickHash(string input)\n{\n var inputBytes = Encoding.UTF8.GetBytes(input);\n var inputHash = SHA256.HashData(inputBytes);\n return Convert.ToHexString(inputHash);\n}\n\nstring hash = QuickHash("...");\n
Run Code Online (Sandbox Code Playgroud)\n上面的代码:
\nHashData
在类上使用新的静态方法SHA256
以避免实例化并每次都必须处理新实例。Convert.ToHexString
方法将哈希字节数组转换为十六进制字符串;消除使用字符串生成器等的麻烦。SHA256
类而不是旧的(现已过时)SHA256Managed
类。注意:您不应该使用此方法对用户密码进行哈希处理。即使添加盐,通用哈希函数(例如 SHA-256)也不再适合用于密码。这对于散列您知道具有高熵的字符串非常有用,例如随机生成的长会话令牌等。为了存储密码,您必须考虑专门为此目的设计的较慢的哈希函数,例如 Bcrypt、Scrypt 或 PBKDF2(后者在 .NET \xe2\x80\x94 中本地可用,请参阅此)
\nAut*_*uto 11
public static string ComputeSHA256Hash(string text)
{
using (var sha256 = new SHA256Managed())
{
return BitConverter.ToString(sha256.ComputeHash(Encoding.UTF8.GetBytes(text))).Replace("-", "");
}
}
Run Code Online (Sandbox Code Playgroud)
你得到不同结果的原因是因为你没有使用相同的字符串编码。您为计算 SHA256 的在线网站提供的链接使用 UTF8 编码,而在您的示例中,您使用了 Unicode 编码。它们是两种不同的编码,因此您不会得到相同的结果。通过上面的示例,您将获得链接网站的相同 SHA256 哈希值。您还需要在 PHP 中使用相同的编码。
每个软件开发人员绝对必须了解 Unicode 和字符集的绝对最低要求(没有任何借口!)
我正在寻找并测试这些答案,Visual Studio 向我展示了 SHA256Managed 现在已过时(此处)
因此,我使用 SHA256 类来代替:
Encoding enc = Encoding.UTF8;
var hashBuilder = new StringBuilder();
using var hash = SHA256.Create();
byte[] result = hash.ComputeHash(enc.GetBytes(yourStringToHash));
foreach (var b in result)
hashBuilder.Append(b.ToString("x2"));
string result = hashBuilder.ToString();
Run Code Online (Sandbox Code Playgroud)
在 PHP 版本中,您可以在最后一个参数中发送“true”,但默认值为“false”。以下算法等效于传递 'sha256' 作为第一个参数时的默认 PHP 哈希函数:
public static string GetSha256FromString(string strData)
{
var message = Encoding.ASCII.GetBytes(strData);
SHA256Managed hashString = new SHA256Managed();
string hex = "";
var hashValue = hashString.ComputeHash(message);
foreach (byte x in hashValue)
{
hex += String.Format("{0:x2}", x);
}
return hex;
}
Run Code Online (Sandbox Code Playgroud)
public string EncryptPassword(string password, string saltorusername)
{
using (var sha256 = SHA256.Create())
{
var saltedPassword = string.Format("{0}{1}", salt, password);
byte[] saltedPasswordAsBytes = Encoding.UTF8.GetBytes(saltedPassword);
return Convert.ToBase64String(sha256.ComputeHash(saltedPasswordAsBytes));
}
}
Run Code Online (Sandbox Code Playgroud)
有史以来最短和最快的方式。只有1行!
public static string StringSha256Hash(string text) =>
string.IsNullOrEmpty(text) ? string.Empty : BitConverter.ToString(new System.Security.Cryptography.SHA256Managed().ComputeHash(System.Text.Encoding.UTF8.GetBytes(text))).Replace("-", string.Empty);
Run Code Online (Sandbox Code Playgroud)