Пишем свой генератор паролей

Недав­но мы писа­ли про уяз­ви­мость паро­лей в фейс­бу­ке и про спо­со­бы их шиф­ро­ва­ния. Наста­ло сде­лать свой соб­ствен­ный гене­ра­тор паро­лей с хешем и сек­рет­ной стро­кой. Прой­ди­те с нами этот путь, и у вас появит­ся соб­ствен­ное при­ло­же­ние для созда­ние паро­лей, кото­рое вы смо­же­те сде­лать сколь­ко угод­но сек­рет­ным, а при жела­нии — воссоздать.

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

Пре­ду­пре­жде­ние. Алго­ритм, кото­рый мы исполь­зу­ем, уяз­вим: если зло­умыш­лен­ник зна­ет ваши сек­рет­ные сло­ва, он смо­жет вос­ста­но­вить пароль. Не исполь­зуй­те этот алго­ритм для защи­ты кри­ти­че­ски важ­ных данных. 

Как устроен наш алгоритм

Мы будем брать адрес сай­та и шиф­ро­вать его с помо­щью алго­рит­ма хеши­ро­ва­ния MD5. Резуль­тат шиф­ро­ва­ния и будет нашим паролем.

О хеши­ро­ва­нии мы уже писа­ли, общий смысл такой: осо­бый алго­ритм шиф­ру­ет текст таким обра­зом, что по ито­го­во­му зашиф­ро­ван­но­му тек­сту невоз­мож­но вос­ста­но­вить исход­ный. Непо­нят­на ни дли­на исход­но­го тек­ста, ни его содержимое.

Сла­бое место алго­рит­ма толь­ко в том, что если зашиф­ро­вать им один и тот же текст, полу­чит­ся один и тот же резуль­тат. То есть алго­ритм рабо­та­ет пред­ска­зу­е­мо: если зашиф­ро­вать адрес mail.yandex.ru с помо­щью алго­рит­ма MD5, все­гда полу­чит­ся B81D1C770FD8F323B57CC73ED7B2546E. Это небезопасно.

Что­бы паро­ли были более уни­каль­ны­ми, мы доба­вим к адре­су сай­та сек­рет­ное сло­во, кото­рое попро­сим у поль­зо­ва­те­ля. И еще одно сек­рет­ное сло­во впи­шем пря­мо в код про­грам­мы. Вот эти два сек­рет­ных сло­ва и будут обес­пе­чи­вать нашу без­опас­ность пароля.

Всё, что оста­лось сде­лать — скле­ить адрес сай­та и два сек­рет­ных сло­ва, зашиф­ро­вать алго­рит­мом MD5, и вуа­ля — у нас будет уни­каль­ный труд­но­чи­та­е­мый пароль, кото­рый никто нико­гда не под­бе­рет перебором.

Готовим каркас

За осно­ву мы возь­мём стра­ни­цу, кото­рую мы созда­ва­ли, когда дела­ли свой спи­сок задач. Если вы её ещё не чита­ли — почи­тай­те, будет гораз­до лег­че пони­мать, что тут про­ис­хо­дит. В нашем слу­чае кар­кас будет выгля­деть так:

<!DOCTYPE html>
<html>
<!-- служебная часть -->

<head>
  <!-- заголовок страницы -->
  <title>Генератор паролей</title>
  <!-- настраиваем служебную информацию для браузеров, можно пока не вникать -->
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- подключаем функцию, которая хеширует строку -->
  <script src="http://thecode.local/wp-content/uploads/2019/05/js-md5.js"></script>
  <style type="text/css">
    /* задаём CSS-стили прямо здесь же, чтобы всё было в одном файле */
  </style>
  <!-- закрываем служебную часть страницы -->
</head>

<body>
  <!-- тут будет наша страница -->
  <script>
    /* тут будет пишем скрипт, который генерирует пароль по нажатию кнопки */
  </script>
</body>
<!-- конец всей страницы -->

</html>

Сохра­ня­ем файл как generator.html, откры­ва­ем в бра­у­зе­ре и видим пока пустую стра­ни­цу с заго­лов­ком вклад­ки «Гене­ра­тор паро­лей» и боль­ше ниче­го. Всё нор­маль­но, так и долж­но быть.

Расставляем содержимое

Вот какой мини­мум инфор­ма­ции дол­жен быть на нашей стра­ни­це с генератором:

  • заго­ло­вок
  • поле для вво­да адре­са сай­та, для кото­ро­го мы дела­ем пароль
  • поле для вво­да клю­че­во­го слова
  • кноп­ка, что­бы на неё нажать и пароль готов
  • место, где будет появ­лят­ся наш пароль, что­бы его отту­да было удоб­но копировать

Раз­ме­стим всё это на стра­ни­це в раз­де­ле <body> в том же порядке:

<!-- ставим всё содержимое в один блок по центру  -->
<div class="container" margin: auto;">
  <!-- заголовок страницы -->
  <h2 class="todo__caption">Генератор паролей</h2>
  <!--делаем отступ -->
  <br>
  <!-- задаём поле ввода для адреса нужного сайта и настраиваем параметры поля -->
  <input type="text" id="site_url" size="50" placeholder="Вставьте адрес сайта, где вам нужен пароль">
  <!--делаем отступ -->
  <br>
  <!-- задаём поле ввода для кодового слова и настраиваем параметры поля -->
  <input type="text" id="keyword" size="50" placeholder="Напишите кодовое слово, чтобы сделать пароль сильнее">
  <!--делаем двойной отступ -->
  <br>
  <br>
  <!-- вставляем кнопку, которая запускает генератор пароля и настраиваем отступы -->
  <button style="font-size: 100%; padding:5px 10px 10px 10px" onclick="generate()">Создать пароль</button>
  <!--выводим сгенерированный пароль -->
  <p>Ваш пароль:</p>
  <div id="pass_text" style="font-weight: bold"></div>
</div>

Сохра­ня­ем под тем же име­нем смот­рим что полу­чи­лось и не рас­стра­и­ва­ем­ся от внеш­не­го вида. Его мы попра­вим на сле­ду­ю­щем шаге.

Настраиваем стили

Сти­ли помо­га­ют улуч­шить внеш­ний вид стра­ни­цы и уста­но­вить нуж­ный раз­мер шриф­та, его рас­по­ло­же­ние, отсту­пы, да и вооб­ще всё, что мы видим на экране. Доба­вим сти­лей в наш гене­ра­тор в раз­дел <style>:

/*задаём общие параметры для всей страницы: шрифт и отступы*/
body {
  text-align: center;
  margin: 10;
  font-family: Verdana, Arial, sans-serif;
  font-size: 16px;
}
/* настраиваем внешний вид полей ввода*/
input {
  display: inline-block;
  margin: 20px auto;
  border: 2px solid #eee;
  padding: 10px 20px;
  font-family: Verdana, Arial, sans-serif;
  font-size: 16px;
}

Сохра­ня­ем, обнов­ля­ем, смот­рим на резуль­тат. Уже получше:

Пишем скрипт

Послед­нее, что нам оста­лось доба­вить в нашу стра­ни­цу — это сам скрипт, кото­рый будет брать со стра­ни­цы все наши дан­ные, соби­рать их в одну стро­ку и из неё делать пароль. Его мы поло­жим в раз­дел <script>:

// задаём переменные, где будем хранить адрес сайта, кодовое слово…
var site, salt;
// …исходные текстовые данные для пароля и сам пароль
var text, password;
// объявляем функцию, которая создаёт пароль и выводит его на экран
function generate() {
  // кладём в соответствующие переменные текстовое значение адреса сайта…
  site = document.getElementById('site_url').value;
  // …и кодового слова
  salt = document.getElementById('keyword').value;
  // подготавливаем исходную строку для пароля и добавляем в неё наш секретный ингредиент
  text = site + salt + 'Misha Polyanin Molodets';
  // на основе этой строки с помощью функции md5, которую мы подключили в самом начале, создаём пароль
  password = md5(text);
  // выводим его на экран
  document.getElementById('pass_text').innerHTML = password;
}

Всё про­грам­ма гото­ва. Про­ве­ря­ем работу:

Общий код страницы:

<!DOCTYPE html>
<html>
<!-- служебная часть -->

<head>
  <!-- заголовок страницы -->
  <title>Генератор паролей</title>
  <!-- настраиваем служебную информацию для браузеров -->
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- подключаем функцию, которая хеширует строку -->
  <script src="http://thecode.local/wp-content/uploads/2019/05/js-md5.js"></script>
  <!-- задаём CSS-стили прямо здесь же, чтобы всё было в одном файле -->
  <style type="text/css">
    /*задаём общие параметры для всей страницы: шрифт и отступы*/
    body {
      text-align: center;
      margin: 10;
      font-family: Verdana, Arial, sans-serif;
      font-size: 16px;
    }

    /* настраиваем внешний вид полей ввода*/
    input {
      display: inline-block;
      margin: 20px auto;
      border: 2px solid #eee;
      padding: 10px 20px;
      font-family: Verdana, Arial, sans-serif;
      font-size: 16px;
    }

    /*закончили со стилями*/
  </style>
  <!-- закрываем служебную часть страницы -->
</head>

<body>
  <!-- началась визуальная часть -->
  <!-- ставим всё содержимое в один блок по центру  -->
  <div class="container" margin: auto;">
    <!-- заголовок страницы -->
    <h2 class="todo__caption">Генератор паролей</h2>
    <!--делаем отступ -->
    <br>
    <!-- задаём поле ввода для адреса нужного сайта и настраиваем параметры поля -->
    <input type="text" id="site_url" size="50" placeholder="Вставьте адрес сайта, где вам нужен пароль">
    <!--делаем отступ -->
    <br>
    <!-- задаём поле ввода для кодового слова и настраиваем параметры поля -->
    <input type="text" id="keyword" size="50" placeholder="Напишите кодовое слово, чтобы сделать пароль сильнее">
    <!--делаем двойной отступ -->
    <br>
    <br>
    <!-- вставляем кнопку, которая запускает генератор пароля и настраиваем отступы -->
    <button style="font-size: 100%; padding:5px 10px 10px 10px" onclick="generate()">Создать пароль</button>
    <!--выводим сгенерированный пароль -->
    <p>Ваш пароль:</p>
    <div id="pass_text" style="font-weight: bold"></div>
  </div>
  <!-- закончилась видимая часть -->
  <!-- пишем скрипт, который будет генерировать пароль по нажатию кнопки -->
  <script>
    // задаём переменные, где будем хранить адрес сайта, кодовое слово…
    var site, salt;
    // …исходные текстовые данные для пароля и сам пароль
    var text, password;
    // объявляем функцию, которая создаёт пароль и выводит его на экран
    function generate() {
      // кладём в соответствующие переменные текстовое значение адреса сайта…
      site = document.getElementById('site_url').value;
      // …и кодового слова
      salt = document.getElementById('keyword').value;
      // подготавливаем исходную строку для пароля и добавляем в неё наш секретный ингредиент
      text = site + salt + 'Misha Polyanin molodets';
      // на основе этой строки с помощью функции md5, которую мы подключили в самом начале, создаём пароль
      password = md5(text);
      // выводим его на экран
      document.getElementById('pass_text').innerHTML = password;
    }
 // закончилась скриптовая часть
  </script>
</body>
<!-- конец всей страницы -->

</html>

Что ещё можно сделать

  • Заме­нить сек­рет­ную стро­ку в коде на свою, что­бы пароль стал ещё уникальнее.
  • Запро­сить сек­рет­ную стро­ку у поль­зо­ва­те­ля в самом нача­ле рабо­ты про­грам­мы с помо­щью коман­ды promt().
  • Сде­лать чере­до­ва­ние заглав­ных и строч­ных букв в пароле.
  • Сде­лать гене­ра­цию паро­лей «на лету», то есть с каж­дым нажа­ти­ем кла­ви­ши. Тогда не нуж­на будет кноп­ка «сге­не­ри­ро­вать пароли»
  • Сде­лать опцию «Доба­вить спец­сим­во­лы», кото­рая будет при­ну­ди­тель­но встав­лять в хеш что-то такое: %:*#@%&. При­го­дит­ся для сай­тов с повы­шен­ны­ми тре­бо­ва­ни­я­ми к безопасности.
  • Обре­зать пароль на девя­ти сим­во­лах и добав­лять меж­ду трой­ка­ми сим­во­лов дефи­сы или дру­гие спец­зна­ки. Кра­си­во будет.
  • Шиф­ро­вать текст два­жды, три­жды, сколь­ко угод­но раз: то есть когда полу­чи­ли резуль­тат, сно­ва про­гна­ли его через шиф­ров­щик MD5. Мож­но даже запро­сить у поль­зо­ва­те­ля, сколь­ко раз он хочет про­гнать свой пароль через шифровальщик.

Пожа­луй, сде­ла­ем это в дру­гой раз.