Я хочу проверить учетные данные пользователя ( имя и пароль ) для Linux пользователей с собственным кодом C# (. NET Core). Учетные данные пользователя в Linux системах обычно хранятся в файле: / etc / shadow .
Например, пользователь с именем " csharp " с паролем " 1337"имеет следующую запись внутри файла / etc / shadow :
string entry = "csharp:$6$qVnvjWpk$DOUTmbC9ROZ6s1h0hCZTYWLFfVeUWDbz8f0EUFPEJEC2UKQV0gRiIfoGpnaA.8i4RCcrGpOEHEd9xrAUDpo3Y/:18337:0:99999:7:::"
Строка перед первым": "имеет вид имя пользователя => entry.Split (":") [0] (csharp)
Символ после первого "$" - это га sh method => entry.Split ("$") [1] (6 = SHA256). Возможные методы: MD5 => 1; SHA256 => 5; SHA512 => 6
Строка после второго "$" - это соль (или ха sh?) => entry.Split ("$") [2 ] (qVnvjWpk)
При использовании программы openssl в системе Linux с " openssl passwd -6 -salt qVnvjWpk 1337 ", тогда он выдаст мне следующий вывод: $6$qVnvjWpk$DOUTmbC9ROZ6s1h0hCZTYWLFfVeUWDbz8f0EUFPEJEC2UKQV0gRiIfoGpnaA.8i4RCcrGpOEHEd9xrAUDpo3Y/
Как видите, вывод 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();
}