Зашифруйте пароль так же, как MySQL

15

Я создал пользователя ... но забыл пароль

mysql> создать пользователя 'blayo' @ '%', идентифицированного как 'right';

Какой инструмент командной строки Linux может зашифровать пароль так же, как это делает MySQL 5.5?

mysql> выберите Пароль, Пользователь из mysql.user
------------------------------------------ + ------- +
* 920018161824B14A1067A69626595E68CB8284CB | Блайо |

... чтобы убедиться, что я использую правильный

$ tool right
* 920018161824B14A1067A69626595E68CB8284CB
Филипп Блайо
источник
2
Почему вы не можете просто войти в систему как администратор и определить новый пароль для blayo? Это определенно быстрее, чем проходить триллионы возможных комбинаций символов, чтобы найти правильную.
Nohillside
Пожалуйста , не размещайте один и тот же вопрос на нескольких сайтах Stack Exchange . Версия DBA также получила ответ, что является пустой тратой усилий.
Жиль "ТАК ... перестать быть злым"

Ответы:

13

Ну, тривиальный (возможно, обман ) способ - запустить:

mysql -NBe "select password('right')"

Это создаст пароль, используя любую схему хэширования паролей, которую использует ваша версия mysql. [ РЕДАКТИРОВАТЬ : добавлен -NB, который избавляется от имен столбцов и таблицы ascii.]

jsbillings
источник
6
И, кстати, это сохранит ваш новый блестящий пароль в виде открытого текста как в журнале MySQL, так и в журнале истории учетной записи bash.
Крейг,
@Craig Чтобы предотвратить и то, и другое, вы можете добавить '' (пробел) прямо перед тем, mysqlчтобы скрыть его из истории bash, и вы можете использовать SET sql_log_off=ON;прямо перед тем, SELECT ...чтобы скрыть его из журнала MySQL.
Мурмель
1
@Murmel спасибо за обновление! Конечно, по умолчанию следует не регистрировать пароли. Безопасность всегда должна быть настройкой по умолчанию.
Крейг
@Craig Чтобы быть справедливым, это уже сделано mysql (v5.7, последняя версия, в которой существует эта функция, удалена с v8.0.11 )) на: 1. клиентской стороне (влияющей .mysql_history), игнорирующей все соответствующие операторы, *PASSWORD*и 2. серверной стороне для несколько stmts (кроме SELECT). См. Руководство по MySQL 5.7 - пароли и ведение журнала и MySQL 5.7 - руководство - ведение журнала клиента mysql
Murmel
Это хорошая обратная связь! К сожалению, все еще довольно много людей, которые по разным причинам (включая меня) застряли, используя версии mysql старше 5.7.
Крейг,
12

Несколько однострочников:

MySQL (может потребоваться добавить -u (пользователь) -p):

mysql -NBe "select password('right')"

Python :

python -c 'from hashlib import sha1; print "*" + sha1(sha1("right").digest()).hexdigest().upper()'

Perl :

perl -MDigest::SHA1=sha1_hex -MDigest::SHA1=sha1 -le 'print "*". uc sha1_hex(sha1("right"))'

PHP :

php -r 'echo "*" . strtoupper(sha1(sha1("right", TRUE))). "\n";'

Рубин :

ruby -e 'require "digest/sha1"; puts "*" + Digest::SHA1.hexdigest(Digest::SHA1.digest("right")).upcase'

Весь вывод:

* 920018161824B14A1067A69626595E68CB8284CB

alexjhart
источник
Спасибо, я связался с вашим ответом на serverfault.com/a/846281/236916
mwfearnley
@alexjhart Могу ли я получить обновление для нового алгоритма хеширования паролей mysql 5.7.8 :)? (может быть, немного подробностей о том, как вы узнали об этом тоже?)
ThorSummoner
6

Это все еще немного удивляет, что MySQL не мешает запутывать пароли в командной строке и в логах. И это единственная причина, по которой я добавляю ответ, а не просто комментирую ответ @Gilles.

Так что, конечно, вы можете просто войти в MySQL как администратор и установить новый пароль для вашего пользователя blayo, как предложено @patrix.

Однако стандартный способ сделать это - использовать функцию пароля MySQL (MySQL), которая в качестве аргумента принимает пароль в виде открытого текста (серьезно?).

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

Разве не было бы лучше иметь небольшую утилиту, которая запрашивала бы пароль, не отражая его на экране или в ваших журналах, а затем предоставила бы вам полученный MySQL-совместимый хеш?

Итак, немного изменив ответ @ Gilles, как насчет небольшого сценария оболочки, использующего Python, как показано ниже. Вы можете легко изменить это, чтобы выполнить оператор SQL для вашей базы данных MySQL, чтобы установить пароль сразу. Но даже не заходя так далеко, просто скопируйте и вставьте полученный хеш в оператор SQL, чтобы обновить таблицу пользователей:

#!/bin/bash

mysqlpwd=$(/usr/bin/python -c 'from hashlib import sha1; import getpass; print "*" + sha1(sha1(getpass.getpass("New MySQL Password:")).digest()).hexdigest()')

echo $mysqlpwd
Craig
источник
@HalosGhost; о чем было редактирование? Это ничего не изменило? ;-)
Крэйг,
Он принудительно выделил синтаксис (как отмечено в сводке по редактированию) и стал очевидным из фактического текста редактирования.
HalosGhost
3
Ах так. Честно говоря, не понимал, что вы сделали (вы, очевидно, добавили <!-- language: lang-bsh -->строку). Handy! Мне это нравится. Благодарность!
Крэйг,
5

Еще один с использованием оболочки:

echo -n 'right' | sha1sum | xxd -r -p |\
sha1sum | tr '[a-z]' '[A-Z]' | awk '{printf "*%s", $1}'

Объяснение:

  1. echo -n печатать без перевода строки
  2. sha1sum первый SHA1
  3. xxd -r -p распаковать хеш
  4. sha1sum второй SHA1
  5. tr '[a-z]' '[A-Z]' преобразовать в верхний регистр
  6. awk '{print "*" $1}' добавить ведущий *

Больше деталей:

Между 2. и 3. awk '{printf "%s", $1}'может быть добавлен необязательный шаг для удаления новой строки и дефиса. Но xxd все равно будет их игнорировать (спасибо dave_thompson_085).

Более того, шаги 5 и 6 можно выполнить сразу, заменив их {print "*" toupper($1)}(спасибо dave_thompson_085).

Murmel
источник
1
awkможет сделать заглавные буквы, и вывод неполной (последнюю) линии терминал incovenient: .. | sha1sum | awk '{print "*" toupper($1)}'. И вам не нужно беспокоиться о NL и даже о дефисе xxd -r -p, они игнорируются.
dave_thompson_085
4

Хеш - это sha1 (sha1 (пароль)) . Поскольку соли нет (что является серьезным недостатком безопасности), вы можете посмотреть хеш в таблице .

Только с инструментами POSIX плюс sha1sumиз GNU coreutils или BusyBox sha1 (sha1 (пароль)) раздражает вычисления, потому что sha1sumкоманда выводит дайджест в шестнадцатеричном формате, и нет стандартного инструмента для преобразования в двоичный файл.

awk "$(printf %s 'right' | sha1sum |
       sed -e 's/ .*//' -e 's/../, 0x&/g' \
           -e 's/^/BEGIN {printf "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c"/' \
           -e 's/$/; exit}/')" | sha1sum

Python имеет стандартные дайджесты в своих стандартных библиотеках, поэтому он простой однострочный.

printf %s 'right' |
python -c 'from hashlib import sha1; import sys; print sha1(sha1(sys.stdin.read()).digest()).hexdigest()'

Или с паролем внутри одной строки:

python -c 'from hashlib import sha1; print sha1(sha1("right").digest()).hexdigest()'
Жиль "ТАК - перестань быть злым"
источник
Мне нравится этот ответ по духу, но он не совсем работает. Когда я нажимаю клавишу ввода, он все еще хочет продолжать читать ввод вместо того, чтобы двигаться дальше. Кроме того, ввод эхом возвращается на экран, что может быть нежелательно. Как насчет чего-то подобного? unix.stackexchange.com/a/155583/37401
Крэйг,
@Craig Как читать интерактивный ввод выходит за рамки вопроса. Я предполагаю, что скрипт уже имеет пароль; обычно он хранится в файле, редко вводится пароль базы данных в интерактивном режиме. Если вы хотите читать интерактивный ввод, вы можете использовать readвстроенную оболочку для чтения строки; stty echoсначала запустите, если хотите отключить эхо и ssty +echoвключить его снова. В Python вы можете использовать getpassмодуль.
Жиль "ТАК - перестань быть злым"
Да, я знаю ... и достаточно справедливо! Я просто ненавижу ужасную безопасность, когда иду дальше, и безопасность MySQL в целом довольно ужасна, поэтому у меня есть склонность к коленопреклонению, когда я пытаюсь внедрить небольшое представление о безопасности, где бы у меня ни была возможность. ;-)
Крейг
1

Если вы создали пользователя и забыли пароль, это то, что вы должны сделать, и это проще.

Это также случалось со мной дюжину раз, когда я делал 10 миллиардов вещей одновременно. Лучший способ восстановить мой пароль был:

остановил сервер MySQL полностью первым

выдал mysqld_safe --skip-grant-tables &

затем я вошел в систему как root без ввода пароля, просто mysql -u mysql-user (он позволяет войти после mysqld_safe)

затем перейдите в таблицу mysql> user и обновите пароль для пользователя

затем вернитесь и перезапустите MySQL

Посмотрим, сработает ли это, и дайте нам знать.

unixmiah
источник
Кажется, это было бы больше для случая, когда вы не можете войти в систему вообще , а не только как пользователь конкретного.
mwfearnley
1

Другой с помощью оболочки

echo -n 'right' | openssl sha1 -binary | openssl sha1 -hex | \
    awk '{print "*"toupper($0)}'

... какие выводы:

*920018161824B14A1067A69626595E68CB8284CB
Крис Мартин
источник
0

MySQL 4.1+ использует двойной SHA1

> SELECT PASSWORD("right")
*920018161824B14A1067A69626595E68CB8284CB

> SELECT SHA1(UNHEX(SHA1("right")))
920018161824B14A1067A69626595E68CB8284CB

sh-3.2# php -r 'echo "*" . sha1(sha1("right", TRUE)). "\n";'
*920018161824b14a1067a69626595e68cb8284cb

Этот алгоритм может быть легко перенесен на другие языки. Разница заключается в том, что хэши паролей в «выберите пароль» всегда начинаются с символа «*».

Диого Нечтан
источник