Есть ли лучший способ обеспечить достойное хеширование паролей в perl cgi-скрипте? - PullRequest
0 голосов
/ 25 февраля 2020

Хорошо, я провел дни, просматривая коды здесь и в других местах, и я просто продолжаю собирать части вместе. Этот сценарий работает для меня, и я все еще проверяю уязвимости безопасности, однако я попытался создать его с должной тщательностью. Я не гений perl и немного ржавый с регулярным выражением.

Цель этого сценария будет использоваться в качестве встроенного ключа для целей чата. Скорее всего, я буду использовать оригинальный крипт для отделения второго ключа, следовательно, дополнительный шаг и запутывание в случае, если кто-то начнет разбирать слои сгенерированных печатных страниц. Я не хочу, чтобы тот же ключ, используемый для входа в систему, хранился в базе данных, что и встроенный, но по понятным причинам им нужно одинаковое значение root У меня может быть слишком много чистящих символов в слишком многих местах, но я решил, почему нет, если я сделаю это отдельным файлом.

use Digest::SHA qw(hmac_sha256_hex);

sub passCrypt {
    chomp(my $userin=$_[0]);            # first passed var is username
    chomp(my $passin=$_[1]);            # second passed var is plaintext password
    $userin = substr $userin, 0, 24;    # protect from DoS attacks by limiting length of input
    $passin = substr $passin, 0, 64;
    $passin =~ tr/\\\?\/\<\>/XPZQJ/;    # clean password replacing \ ? / < > with safe chars
    $passin =~ s/0x[0-9a-fA-F]//g;      # clean password from hex 0x0 - 0xF
    $userin =~ s/[^\w]//g;              # clean username from any non-word characters (a-z A-Z 0-9 _)
    $userin =~ s/[_]//g;                # clean username from the _ (for salt)
    $userin = lc($userin);              # all lowercase username
    my $salt = substr($userin, 1, 1) . substr($userin, -2, 1);  # make salt from first and last of username
    my $clnpass = crypt($passin,$salt);  # use basic crypt to prevent plain text password being utilized beyond this point
    $clnpass = substr $clnpass, 2;  # strip salt from beginning of pass
    $clnpass =~ tr/\/\\\!\@\#\$\%\^\&\*\(\)\[\]\{\}\|\?\=\+\-\_\<\>\:\;\"\'\`\,\./1234567890123456789012345678901/;  # make pass filename safe (replacement to keep consistent length)
    $clnpass =~ tr/abcdefghijklmnopqrstuvwxyz1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZ/WXYZwxcd123efghFGHIJij4ABlmnopqNOPQRrstuCDEKL567MSkyzTUVa890/;  # added obfuscation
    $clnpass = reverse($clnpass);  # more obfuscation
    my $cryptpass = hmac_sha256_hex($clnpass, chr(0x0b) x 32);  # final crypt with sha256
    return $cryptpass; 
}

Я выкладываю это здесь на случай, если кто-то другой, выполняющий поиск, сталкивается с подобным вопросы, которые у меня есть, и надеюсь на множество предложений по улучшению. Есть ли лучший способ обеспечить достойное хеширование пароля в perl cgi-скрипте? Сначала я заглянул в Crypt :: Eksblowfi sh :: Bcrypt, но мой хост не имеет этого пакета. Заранее спасибо.

Редактировать: Мне разъяснили, что все, что я делаю, это хэширование, поэтому я заменил указанный текст.

Ответы [ 2 ]

2 голосов
/ 25 февраля 2020

Безопасность вашего кода в основном зависит от crypt и hmac_sha256. Остальное - запутывание. Учитывая, что сценарий, вероятно, находится в той же системе, что и хеши паролей (здесь нет шифрования, просто хеширование), маловероятно, что обфускация действительно поможет злоумышленнику - тот, кто получит доступ к хешам паролей, может также получить доступ к вашему коду. .

Это оставляет crypt и hmac_sha256, которые обе являются функциями с быстрой sh, так что по сути вы создаете быструю функцию для хеширования пароля. Но использование быстрого ха sh означает, что злоумышленник может быстро перебить любые существующие хеши. Вот почему важно, чтобы критерии хэшей паролей были достаточно медленными.

Подробнее о том, как правильно иметь sh пароли, см. Как безопасно иметь sh пароли?, Пожалуйста, не изобретайте свои собственные, а используйте вместо этого существующие методы. В области безопасности лучше всего полагаться на проверенные методы, а не изобретать свои собственные методы, которые могут выглядеть безопасными для вас, но не для других.

0 голосов
/ 26 февраля 2020

Так что, следуя всем советам Штеффена, это то, чем я закончил, изменит некоторые детали по сравнению с тем, что я на самом деле использую, потому что это, вероятно, похоже на то, что я буду использовать, и, честно говоря, безопасность кажется глупой, если я продолжу публиковать свои сценарии.

use Digest::SHA qw(hmac_sha512_hex hmac_sha256_base64);
use Crypt::PBKDF2;

my $hash = &MakeHash($username,$password); #test
print &MakeSessionID($hash); #test

sub MakeHash {
  chomp(my $userin=$_[0]);  #i do this as a habbit when I work with files, I know this info should not be coming from a file, I will clean it up later
  chomp(my $passin=$_[1]);
  $userin = substr $userin, 0, 24;  #keeping this to prevent accidents while I keep working
  $passin = substr $passin, 0, 64;
  my $hashkey = hmac_sha256_base64($userin,$userin);
  my $pbkdf2 = Crypt::PBKDF2->new(hash_class => 'HMACSHA1',iterations => 200000,output_len => 24); #these are not the values im actually using but close enough
  my $result = $pbkdf2->PBKDF2_base64($hashkey,$passin);
  return $result; }

sub MakeSessionID {
  chomp(my $passin=$_[0]);
  my $salt = time*2;
  my $result = hmac_sha512_hex($passin, $salt);
  return $result; }

явно отсутствуют мои функции, которые используют это, но да

...