Вопрос или проблема
Я хотел бы сгенерировать случайную строку (например, пароли, имена пользователей и т. д.). Должна быть возможность задать необходимую длину (например, 13 символов).
Какие инструменты я могу использовать?
(По соображениям безопасности и конфиденциальности предпочтительно, чтобы строки генерировались офлайн, а не онлайн на сайте.)
Мой любимый способ сделать это – использовать /dev/urandom
вместе с tr
, чтобы удалить ненужные символы. Например, чтобы получить только цифры и буквы:
tr -dc A-Za-z0-9 </dev/urandom | head -c 13; echo
В качестве альтернативы, чтобы включить больше символов из списка специальных символов пароля OWASP:
tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' </dev/urandom | head -c 13; echo
Если у вас есть проблемы с tr
, который жалуется на входные данные, попробуйте добавить LC_ALL=C
вот так:
LC_ALL=C tr -dc 'A-Za-z0-9!"#$%&'\''()*+,-./:;<=>?@[\]^_`{|}~' </dev/urandom | head -c 13; echo
tr
также имеет класс символов для графических символов, который немного более читаем. Ограничив его до C
локали, вы должны получить такой же тип вывода, что и в вышеприведенном явном списке символов:
LC_ALL=C tr -dc '[:graph:]' </dev/urandom | head -c 13; echo
Я использую команду openssl
, швейцарский армейский нож криптографии.
openssl rand -base64 12
или
openssl rand -hex 12
Чтобы сгенерировать случайный пароль, вы можете использовать pwgen
:
pwgen
генерирует случайные, бессмысленные, но произносимые пароли. Эти пароли содержат либо только строчные буквы, либо смешанные строчные и заглавные буквы, либо цифры. Заглавные буквы и цифры размещаются так, чтобы облегчить запоминание их положения при запоминании только слова.
Сгенерируйте 7 паролей длиной 13:
geek@liv-inspiron:~$ pwgen 13 7
Eu7Teadiphaec giepahl3Oyaiy iecoo9Aetaib4 phaiChae6Eivi athoo3igee8Co
Iphu4ufeDeelo aesoYi2lie9he
Как упоминалось в комментариях, вы можете избежать снижения энтропии, используя аргумент -s
(то есть генерировать более безопасные, совершенно случайные, но трудные для запоминания пароли):
geek@liv-inspiron:~$ pwgen -s 13 7
eAfycrPlM4cYv 4MRXmZmyIVNBp D8y71iqjG7Zq7 FQRHcserl4R8O yRCUtPtV3dsqV
0vJpp2h0OrgF1 QTp7MKtJyTrjz
Для пользователей brew
смотрите здесь.
Чтобы сгенерировать случайные имена пользователей, вы можете использовать gpw
:
Этот пакет генерирует произносимые пароли. Он использует статистику трехбуквенных комбинаций (триграмм), взятых из любых словарей, которые вы ему предоставляете.
Сгенерируйте 7 паролей (имен пользователей) длиной 13:
geek@liv-inspiron:~$ gpw 7 13
sreepoidahsas
risadiestinge
ntodynesssine
deodstestress
natinglumperm
riasigentspir
enderiferback
Вдохновленный Пабло Репетто, я пришел к этому легкому для запоминания решению:
shuf -er -n20 {A..Z} {a..z} {0..9} | tr -d '\n'
-e
выводит результат
-r
позволяет любому символу появляться несколько раз
-n20
запрашивает случайную строку длиной 20 символов
{A..Z} {a..z} {0..9}
определяет допустимые классы символов
shuf
является частью coreutils и широко доступен или по крайней мере был портирован.
Вот как я это делаю. Это генерирует 10 случайных символов. Вы можете оптимизировать это, заменив “fold” на другие инструменты обработки строк.
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 10 | head -n 1
Чтобы создать пароль с максимальной энтропией, которую возможно достичь с помощью стандартных инструментов Linux, которые встроены в каждую дистрибуцию, я использую:
< /dev/urandom tr -cd "[:print:]" | head -c 32; echo
Это выводит все печатаемые символы ASCII – от 32 (пробел) до 126 ( тилда, ~
). Длину пароля можно контролировать с помощью флага -c
у head
. Существуют также другие возможные наборы символов в tr
(чтобы не включать пробел, используйте только символы с 33 по 126, введите [:graph:]
).
Используйте команду xxd
для задания длины (через -l
), которая работает как в Linux, так и в macOS.
Смотрите справочную страницу xxd(1)
или Учебник по команде Linux xxd для начинающих (с примерами).
xxd -l16 -ps /dev/urandom
В зависимости от уровня случайности, который вы хотите, вы можете просто использовать встроенную переменную $RANDOM
в bash (также zsh
и ksh
, возможно, и другие):
$ echo $RANDOM | tr '[0-9]' '[a-z]'
bfeci
$ echo $RANDOM | tr '[0-9]' '[a-z]'
cijjj
Методы, считывающие данные непосредственно из /dev/urandom
, значительно проще, но для завершенности вы также можете использовать $RANDOM
:
echo $(for((i=1;i<=13;i++)); do printf '%s' "${RANDOM:0:1}"; done) | tr '[0-9]' '[a-z]'
Важно: это решение будет лишь создавать случайные строки, используя первые 10 букв алфавита. Достаточно ли этого для вас, зависит от того, для чего вам это нужно.
Я использую:
base64 < /dev/urandom | tr -d 'O0Il1+/' | head -c 44; printf '\n'
Это дает мне 57 возможных символов. Строку можно копировать и вставлять (удалив +
и /
) или распечатать и перепечатать, так как трудные для различения символы (I1lO0
) были удалены.
- 44 символов дают мне: log2(5744) > 256.64 бит энтропии
- 22 символов дают мне: log2(5722) > 128.32 бит энтропии
Мне это нравится, потому что:
- команда проста для ввода и запоминается
- использует стандартные системные инструменты – без дополнительных бинарников
- не “тратит” много случайности (использует 89% случайных битов, которые получает по сравнению с ~24% для решений, которые напрямую передают в tr)
- 22 и 44 символа довольно хорошо сочетаются (чуть выше обычных степеней двойки)
- вывод можно легко выбрать, вставить или распечатать и перепечатать с минимальным человеческим уровнем ошибок
- короче, чем закодированные в шестнадцатеричном формате (32 и 64 вместо 22 и 44) решения, такие как md5sum/sha1sum и т. д.
Кредиты https://unix.stackexchange.com/a/230676/9583 и особенно комментариев для моего первоначального вдохновения.
APG
включен по умолчанию в некоторых дистрибуциях Linux.
Для генерации паролей размером от 5 до 10 в подмножествах Специальный, Цифровой, Заглавный и Низкий, команда:
apg -MSNCL -m 5 -x 10
И возвращает
@OpVeyhym9
3:Glul
3DroomIc?
hed&Os0
NefIj%Ob3
35Quok}
Как говорится @landroni в комментарии.
@Brandin объяснил в комментарии к другому ответу, как получить не более 100 байт из /dev/urandom
с использованием head -c 100
. Другой способ сделать это – с помощью dd
:
tr -dc A-Za-z0-9 < /dev/urandom | dd bs=100 count=1 2>/dev/null
Команда 2>/dev/null
в конце команды dd
используется для подавления вывода “… записей в / … записей вывода”.
Я не знаю никаких существенных преимуществ/недостатков между этими двумя методами.
У меня была проблема с обеими методами tr
, которые жаловались на входные данные. Я подумал, что это потому, что ему не нравится получать двоичные входные данные, и, следовательно, предложил сначала отфильтровать /dev/random
с iconv -c -t US
. Однако Жиль предложил другую диагностику и решение, которое для меня сработало:
LC_ALL=C tr -dc A-Za-z0-9 </dev/urandom | dd bs=100 count=1 2>/dev/null
Вы можете использовать один из инструментов md5
, который имеет именно такую цель. В случае создания совершенно случайного пароля вы можете использовать md5pass
. Это очень простой инструмент для использования и очень полезный, поскольку вы можете использовать “нормальный текст” вместе с “солью”, чтобы получать одну и ту же битовую конструкцию пароля, которую вы можете восстановить позже, или, альтернативно, вы можете захотеть каждый раз получать совершенно случайный пароль. Общий способ использования:
md5pass [пароль] [соль]
где пароль
– это выбранное слово, которое будет использоваться для создания случайной строки, а соль
– это прыжок в байтах, который будет использоваться. Так:
md5pass слово
$1$.MUittVW$j.XDTF1QRnxqFdXRUiSLs0
Это создаст для вас “случайный последовательность” пароля. Если вы не используете соль
, то вы можете не иметь возможности восстановить ту же строку позже.
Тем не менее, если вы используете соль
вроде этого:
md5pass слово 512
$1$512$.0jcLPQ83jgszaPT8xzds0
вы можете создать последовательность, которую сможете восстановить, если используете слово вместе с той же солью (или прыжком), если это было первоначально определено.
Эти две команды генерируют случайные пароли и фразы, соответственно.
shuf --random-source=/dev/urandom --repeat --head-count=20 file_with_characters | tr --delete '\n'
shuf --random-source=/dev/urandom --repeat --head-count=7 file_with_words | tr '\n' ' '
Генератор паролей требует файл_with_characters, содержащий все символы, которые вы хотите использовать для пароля, по одному символу в строке, и ровно один раз каждый. Файл не должен содержать пустых строк, а строки должны заканчиваться знаком новой строки.
Генератор фраз требует файл_with_words, содержащий все слова, которые вы хотите использовать в фразе, по одному слову в строке и ровно один раз каждое. Файл не должен содержать пустых строк, а строки должны заканчиваться знаком новой строки.
Опция –head-count указывает длину пароля – в символах – или фразы – в словах.