Чтобы закрепить пройденный на курсере курс по AngularJS
, я переписал свой старый генератор паролей OktoPass заново: переверстал страницу с Bootstrap
, избавился от jQuery
и переделал сам механизм генерации паролей. Ссылка на сервис: password.axisful.info
Это было занятно, у меня получилось веб-приложение со стильной шёрсткой и адаптивной вёрсткой, а в процессе я написал пару велосипедов для серверного микро-движка и фронтенда, вроде поддержки переводов и работы с URL.
Далее я опишу некоторые ключевые моменты, на которых работает OktoPass.
Раньше приложение полагалось на встроенный в JavaScript Math.random()
, который выдаёт не криптографически стойкие случайные числа. Для задач, связанных с безопасностью, такой метод не подходит.
Вместо этого рекомендуется использовать современный интерфейс Web Crypto API, который использует генератор псевдо-случайных чисел с начальным зерном, подробнее на MDN web docs. Технология экспериментальная, и поддерживается не всеми браузерами, поэтому приложение проверяет поддержку Web Crypto API
, и если её нет, то выполняет запрос на сервер, где пароль генерируется гарантированно с соблюдением условий безопасности.
JavaScript: генерация случайной строки
В сердце гирлянд из сервисов, компонент и директив находится смысл всего приложения:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | /** * Метод, который возвращает пароль. * passwordLength — это приватное поле сервиса, * его значение передаётся из DOM-контрола * * @return {String} */ function getPassword() { var pass = '', max = passwordLength; while (max--) { pass += getRandomSym(); } return pass; }; /** * Метод возвращает случайный символ из поля symbols, * которое содержит словарь — набор дозволенных в пароле символов. * * @return {String|Number} */ function getRandomSym() { return symbols[Math.floor(getRandom() * symbols.length)]; } /** * Выбрать доступный на клиенте интерфейс * @type {window.Crypto} */ var cryptoObj = window.crypto || window.msCrypto; // IE 11 /** * Метод выдаёт случайное число от 0 до 1, и на самом деле, * работает проще, чем выглядит. * * @return {number} */ function getRandom() { // Массив из одного 32-битного целого беззнакового числа var arr = new Uint32Array(1); // Заполнить массив случайными значениями cryptoObj.getRandomValues(arr); // Получить число с плавающей точкой от 0 до 1: // 0xffffffff + 1 это максимальная значение unsigned long (uint32_t) числа return arr[0] / (0xffffffff + 1); } |
PHP: генерация случайной строки
В PHP
ситуация проще: в 7-й версии появилась функция random_int, которая выдаёт криптографически безопасное случайное целое число в заданном диапазоне (включительно):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | /** * @param int $length * @return string */ function generate(int $length): string { $password = []; $storage = [1, 2, 3, 'a', 'b']; // etc. $max = count($storage) - 1; for ($i = 0; $i < $length; $i++) { $password[] = $storage[random_int(0, $max)]; } return implode('', $password); } |
Для PHP 5.6
версии (последняя поддерживаемая ветки 5.x) можно установить полифил random_compat
:
1 | composer require paragonie/random_compat |
Подключить файл библиотеки и код в предыдущем примере будет работать так же (без объявления типов, конечно):
1 | require_once APP_PATH . '/vendor/paragonie/random_compat/lib/random.php'; |
Полифил поставляет функции random_bytes
и random_int
, больше примеров на гитхабе.
Ссылки
Старая версия генератора описана в этой статье.
Для разработки я использовал:
- TinyPNG — онлайн-оптимизатор изображений, сжимает лучше, чем пару консольных программ, что у меня были установлены, и существенно лучше, чем GIMP.
- Responsive Image Breakpoints Generator — на этом ресурсе я разрезал большую картинку для фона на разные размеры под разные разрешения дисплеев.
- http://caniuse.com/#feat=getrandomvalues — статистика о доступности
Web Crypto API
в браузерах. - Web Crypto API на MDN web docs.