PowerShell · 07.06.2023

Страсти по GetStringHash

Немного расскажу о перипетиях, которые привели к появлению этого скрипта.

На одном маленьком сервере жил-был старенький веб-проект, где отслеживался прогресс энного процесса в организации. И всё было хорошо до тех пор пока не выяснилось, что не работает страничка добавления нового пользователя. Разумеется, выяснилось это в самый неподходящий момент.

Условный adduser.php просто отправлялся в долгий путь по просторам ошибки №500. В конечном итоге, история с решением проблемы потянула бы на хороший стендап.

Однако на тот момент самым приемлемым решением, как мне показалось, было добавление пользователя напрямую в базу данных.

Побродив по таблицам, я нашёл заветную — users. Разработчик проекта подошёл к делу со всей серьёзностью и хранение паролей реализовал на основе контрольных сумм. Длина хэша составляла 32 символа. MD5, — подумал Штирлиц.

Мне оставалось только сгенерировать контрольную сумму пароля и заполнить все сопутствующие поля таблицы. Для вычисления хэша пароля я и применил магию PowerShell с помощью пространства System.Web. Получилась функция GetStringHash:

function GetStringHash
{
    param
    (
      [Parameter(mandatory=$true)]
      [ValidateNotNullOrEmpty()]
      [string]$text,
      [Parameter(mandatory=$true)]
      [ValidateNotNullOrEmpty()]
      [ValidateSet('MD5', 'SHA1', 'SHA256', 'SHA512')]
      [string]$hashtype
    )

  [Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null
  $hash = [System.Web.Security.FormsAuthentication]::HashPasswordForStoringInConfigFile($text, $hashtype)
  return ($hash).ToLower()
}

Как видно из кода, GetStringHash принимает аргументы -text и -hashtype. Последний аргумент ограничен рамками 4-х методов вычисления контрольных сумм: MD5, SHA1, SHA256 и SHA512. Подсказки прилагаются. Аргумент -text принимает значение пользовательской строки для вычисления контрольной суммы.

Уже чуть позже я закатал функцию в рамки скрипта:

# Заголовок скрипта #
[System.Console]::Title = "Вычисление контрольной суммы строки"

# Функция получения хэша #
function GetStringHash
{
    param
    (
      [Parameter(mandatory=$true)]
      [ValidateNotNullOrEmpty()]
      [string]$text,
      [Parameter(mandatory=$true)]
      [ValidateNotNullOrEmpty()]
      [ValidateSet('MD5', 'SHA1', 'SHA256', 'SHA512')]
      [string]$hashtype
    )

  [Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null
  $hash = [System.Web.Security.FormsAuthentication]::HashPasswordForStoringInConfigFile($text, $hashtype)
  return ($hash).ToLower()
}

# Запрос фразы #
$phrase = Read-Host "Введите фразу для вычисления"

# Получаем хэш строки и помещаем её в буфер обмена #
$gethash = GetStringHash -text $phrase -hashtype MD5 | Set-Clipboard

Скрипт спросит у пользователя фразу, вычислит хэш и поместит его в буфер обмена.