用Sha256散列string
我尝试使用SHA256散列string,我使用下面的代码:
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; } }
然而,这段代码给我的朋友php,以及在线生成器(如这个生成器 )显着不同的结果,
有谁知道错误是什么? 不同的基地?
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
一定适合。 如果您的目标是与朋友的代码保持完美的兼容性,即使是非ASCIIinput,您也最好使用非ASCII字符(例如é
和家
testing一些testing用例,看看您的结果是否仍然匹配。 如果不是,你将不得不弄清楚你的朋友使用的是什么编码。 它可能是Unicode发明之前stream行的8位“代码页”之一。 (再次,我认为Windows是任何人仍然需要担心“代码页”的主要原因。)
我也遇到了另一种实施方式的问题,但是我忘记了自从2年前以来我所得到的结果。
static string sha256(string randomString) { SHA256Managed crypt = new SHA256Managed(); string hash = String.Empty; byte[] crypto = crypt.ComputeHash(Encoding.ASCII.GetBytes(randomString), 0, Encoding.ASCII.GetByteCount(randomString)); foreach (byte theByte in crypto) { hash += theByte.ToString("x2"); } return hash; }
当我input“abcdefghi2013”之类的东西时,会给出不同的结果,导致我的login模块出现错误。 然后,我尝试按照Quuxplusone的build议相同的方式修改代码,并将编码从ASCII更改为UTF8,然后终于工作!
static string sha256(string randomString) { System.Security.Cryptography.SHA256Managed crypt = new System.Security.Cryptography.SHA256Managed(); System.Text.StringBuilder hash = new System.Text.StringBuilder(); byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(randomString), 0, Encoding.UTF8.GetByteCount(randomString)); foreach (byte theByte in crypto) { hash.Append(theByte.ToString("x2")); } return hash.ToString(); }
再次感谢Quuxplusone的精彩和详细的答案! 🙂
在PHP版本中,您可以在最后一个参数中发送“true”,但默认值为“false”。 当传递'sha256'作为第一个参数时,以下algorithm等同于默认的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; }
在散列之前,你应该使用你的密码:
private const string _salt = "P&0myWHq"; private static string CalculateHashedPassword(string clearpwd) { using (var sha = SHA256.Create()) { var computedHash = sha.ComputeHash(Encoding.Unicode.GetBytes(clearpwd+_salt)); return Convert.ToBase64String(computedHash); } }