C#:使用来自 /etc/shadow 的 linux 用户的 salt 验证密码哈希 (SHA512)
Posted
技术标签:
【中文标题】C#:使用来自 /etc/shadow 的 linux 用户的 salt 验证密码哈希 (SHA512)【英文标题】:C#: Verify password hash (SHA512) with salt for linux user from /etc/shadow 【发布时间】:2020-07-04 18:54:00 【问题描述】:我想使用本机 C# 代码 (.NET Core) 验证 Linux 用户的用户凭据(名称和密码)。 Linux 系统上的用户凭据通常存储在文件中:/etc/shadow。
例如,名为“csharp”且密码为“1337”的用户在文件/etc/shadow中有以下条目:
string entry = "csharp:$6$qVnvjWpk$DOUTmbC9ROZ6s1h0hCZTYWLFfVeUWDbz8f0EUFPEJEC2UKQV0gRiIfoGpnaA.8i4RCcrGpOEHEd9xrAUDpo3Y/:18337:0:99999:7:::"
第一个“:”之前的字符串是用户名 => entry.Split(":")[0] (csharp)
第一个“$”之后的字符是哈希方法 => entry.Split("$")[1] (6 = SHA256)。可能的方法是:MD5 => 1; SHA256 => 5; SHA512 => 6
第二个“$”之后的字符串是盐(或哈希?)=> entry.Split("$")[2] (qVnvjWpk)
在 Linux 系统上使用“openssl passwd -6 -salt qVnvjWpk 1337”程序openssl时,它会给我以下输出:
<pre>$6$qVnvjWpk$DOUTmbC9ROZ6s1h0hCZTYWLFfVeUWDbz8f0EUFPEJEC2UKQV0gRiIfoGpnaA.8i4RCcrGpOEHEd9xrAUDpo3Y/</pre>
如您所见,openssl 输出是 /etc/shadow 条目的一部分:
entry.Split(":")[1] == openssl_output
但是如何使用原生 csharp 代码而不使用程序 openssl 来完成呢?
我有以下方法可以做到这一点。
CheckCredentials("csharp", "1337");
public static bool CheckCredentials(string username, string password)
string[] shadow = File.ReadAllLines("/etc/shadow");
foreach(string entry in shadow)
// entry = csharp:$6$qVnvjWpk$DOUTmbC9ROZ6s1h0hCZTYWLFfVeUWDbz8f0EUFPEJEC2UKQV0gRiIfoGpnaA.8i4RCcrGpOEHEd9xrAUDpo3Y/:18337:0:99999:7:::
if(entry.Split(":")[0] == username)
// hash = 6f0ac65fe01188660aad900bfe16c566ebf0e56c0a7d4a15bd831049108de80bd3a2fbf1a8b91662433a40458ec208a207cab073f190bd65b889e95e4fca8e09
// $6 => SHA512
string hash = HashSHA512(password);
// salt = qVnvjWpk
string salt = entry.Split("$")[2];
// >>> how to check now the given password "1337"? <<<
break;
throw new Exception($"User 'username' was not found");
return false;
public static string HashSHA512(string input)
SHA512Managed crypt = new SHA512Managed();
StringBuilder hash = new StringBuilder();
byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(input));
foreach (byte append in crypto)
hash.Append(append.ToString("x2"));
return hash.ToString();
【问题讨论】:
您找到解决方案了吗?我需要做同样的事情,使用新应用程序验证旧数据库中的密码。好像是extremely complicated。我最好为此找到一个库。 【参考方案1】:确实很复杂。我发现了一些实现original specificationin C#的代码。它是 SHA-512 支持的 extended。然后我为它制作了some more changes,现在我可以自己使用它了。 Here's the code.(这个答案真的没什么好说的了……)
【讨论】:
以上是关于C#:使用来自 /etc/shadow 的 linux 用户的 salt 验证密码哈希 (SHA512)的主要内容,如果未能解决你的问题,请参考以下文章