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;
}
}
그러나이 코드는 내 친구 PHP와 온라인 생성기 (예 : This generator ) 와 비교하여 상당히 다른 결과를 제공합니다
누구든지 오류가 무엇인지 알고 있습니까? 다른 기지?
답변
Encoding.Unicode
UTF-16 (역사적 이유로 Windows 세계에서는 사용되었지만 다른 사람은 사용하지 않는 이중 너비 인코딩)에 대한 Microsoft의 오해의 소지가 있습니다. 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 문자와 몇 가지 테스트 케이스를 시도 할 것입니다 é
및 家
당신의 결과는 여전히 일치 여부를 참조하십시오. 그렇지 않은 경우 친구가 실제로 사용하는 인코딩을 파악해야합니다. 유니 코드가 발명되기 전에 널리 사용되었던 8 비트 “코드 페이지”중 하나 일 수 있습니다. (또, Windows는 누구나 “코드 페이지”에 대해 여전히 걱정해야하는 주된 이유라고 생각합니다.)
답변
나는 또 다른 스타일의 구현 으로이 문제를 겪었지만 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;
}
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();
}
훌륭하고 자세한 답변을 위해 다시 Quuxplusone에 감사드립니다! 🙂
답변
public static string ComputeSHA256Hash(string text)
{
using (var sha256 = new SHA256Managed())
{
return BitConverter.ToString(sha256.ComputeHash(Encoding.UTF8.GetBytes(text))).Replace("-", "");
}
}
다른 결과를 얻는 이유는 동일한 문자열 인코딩을 사용하지 않기 때문입니다. SHA256을 계산하는 온라인 웹 사이트에 넣은 링크는 UTF8 인코딩을 사용하지만 예제에서는 유니 코드 인코딩을 사용했습니다. 그것들은 두 가지 다른 인코딩이므로 동일한 결과를 얻지 못합니다. 위의 예제를 사용하면 연결된 웹 사이트의 동일한 SHA256 해시가 나타납니다. PHP에서도 동일한 인코딩을 사용해야합니다.
절대적으로 모든 소프트웨어 개발자는 절대적으로, 유니 코드 및 문자 집합에 대해 반드시 알아야합니다 (변명 없음).
답변
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;
}
답변
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));
}
}
답변
가장 짧고 빠른 방법. 단 한 줄!
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);
답변
이것은 .NET Core 3.1에서 작동합니다.
그러나 .NET 5 미리보기 7에는 없습니다.
using System;
using System.Security.Cryptography;
using System.Text;
namespace PortalAplicaciones.Shared.Models
{
public class Encriptar
{
public static string EncriptaPassWord(string Password)
{
try
{
SHA256Managed hasher = new SHA256Managed();
byte[] pwdBytes = new UTF8Encoding().GetBytes(Password);
byte[] keyBytes = hasher.ComputeHash(pwdBytes);
hasher.Dispose();
return Convert.ToBase64String(keyBytes);
}
catch (Exception ex)
{
throw new Exception(ex.Message, ex);
}
}
}
}