Топ питань
Часова шкала
Чат
Перспективи

Генератор випадкових паролів

З Вікіпедії, вільної енциклопедії

Remove ads

Генератор випадкових паролів — це програмне забезпечення або апаратний пристрій, який отримує вхідні дані від генератора випадкових чи псевдовипадкових чисел і автоматично генерує пароль. Випадкові паролі можна згенерувати вручну, використовуючи прості джерела випадковості, такі як кубики[en] чи монети, або їх можна створити за допомогою комп'ютера.

Хоча в Інтернеті є багато прикладів програм для генерування «випадкових» паролів, генерація випадкових паролів може бути складною, і багато програм не генерують випадкові символи таким чином, щоб забезпечити надійну безпеку. Загальною рекомендацією є використання інструментів безпеки з відкритим кодом де це можливо, оскільки вони дозволяють незалежно перевіряти якість використовуваних методів. Зауважте, що просте генерування пароля навмання не гарантує, що пароль є надійним, оскільки можливо, хоча й дуже малоймовірно, створити пароль, який легко вгадати або зламати. Насправді немає жодної потреби, щоб пароль створювався абсолютно випадковим процесом: його просто має бути достатньо важко вгадати.

Генератор паролів може бути частиною менеджера паролів. Коли політика паролів[en] забезпечує виконання складних правил, може бути легше використовувати генератор паролів на основі цього набору правил, ніж створювати паролі вручну.

Більшості людей важко запам'ятати довгі рядки випадкових символів. Мнемонічні хеші, які оборотно перетворюють випадкові рядки в паролі, які краще запам'ятовуються, можуть значно покращити легкість запам'ятовування. Оскільки хеш може бути оброблений комп'ютером для відновлення вихідного 60-бітного рядка, він містить принаймні стільки ж інформації, скільки вихідний рядок.[1] Подібні прийоми використовуються в спортивному запам'ятовуванні.

Remove ads

Наївний підхід

Узагальнити
Перспектива

Ось два зразки коду, які програміст, який не знайомий з обмеженнями генераторів випадкових чисел у стандартних бібліотеках програмування, може застосувати:

C

# include <time.h>
# include <stdio.h>
# include <stdlib.h>

int
main(void)
{
    /* Length of the password */
    unsigned short int length = 8;

    /* Seed number for rand() */
    srand((unsigned int) time(0));

    /* ASCII characters 33 to 126 */
    while (length--) {
        putchar(rand() % 94 + 33);
    }

    printf("\n");

    return EXIT_SUCCESS;
}

У цьому випадку стандартна функція C rand, яка є генератором псевдовипадкових чисел, спочатку заповнюється за допомогою функції C time, але в подальших ітераціях замість неї використовується rand. Відповідно до стандарту ANSI C, time повертає значення типу time_t, яке визначається реалізацією, але найчастіше це 32-розрядне ціле число, що містить поточну кількість секунд з 1 січня 1970 року (див.: час Unix). У році є приблизно 31 мільйон секунд, тому зловмисник, який знає рік (проста справа в ситуаціях, коли часта зміна пароля вимагається політикою паролів) та ідентифікатор процесу, з яким було згенеровано пароль, стикається з відносно невеликою кількістю, за криптографічними стандартами варіантів для тестування. Якщо зловмисник знає точніше, коли був згенерований пароль, він стикається з іще меншою кількістю кандидатів для тестування — серйозний недолік у цій реалізації.

У ситуаціях, коли зловмисник може отримати зашифровану версію пароля, таке тестування можна виконати досить швидко, щоб кілька мільйонів пробних паролів можна було перевірити за лічені секунди. Дивіться: злом паролів.

Функція rand представляє іншу проблему. Усі генератори псевдовипадкових чисел мають внутрішню пам'ять або стан. Розмір цього стану визначає максимальну кількість різних значень, які він може створити: n-розрядний стан може створити щонайбільше різних значень. У багатьох системах rand має 31 або 32-бітний стан, що вже є значним обмеженням безпеки. Документація Microsoft не описує внутрішній стан реалізації rand стандартної бібліотеки C у Visual C++, але вона має лише 32767 можливих виходів (15 біт) на виклик.[2] Корпорація Microsoft рекомендує використовувати іншу, більш безпечну функцію, rand_s. Вихід rand_s є криптографічно захищеним, згідно з Microsoft, і він не використовує початкове значення, завантажене функцією srand. Однак його інтерфейс програмування відрізняється від rand.[3]

PHP

function pass_gen(int $length = 8): string
{
    $pass = array();
    for ($i = 0; $i < $length; $i++) {
        $pass[] = chr(mt_rand(32, 126));
    }

    return implode($pass);
}

У другому випадку використовується функція PHP microtime[4], яка повертає поточну позначку часу Unix із мікросекундами. Це збільшує кількість можливостей, але той, хто добре здогадується, коли було згенеровано пароль, наприклад, дату початку роботи працівника, все ще має досить малий простір для пошуку. Крім того, деякі операційні системи не забезпечують час для мікросекундної роздільної здатності, що різко зменшує кількість варіантів. Нарешті, функція rand[5] зазвичай використовує базову функцію C rand і може мати невеликий простір станів, залежно від того, як вона реалізована. Альтернативний генератор випадкових чисел, mt_rand, який базується на генераторі псевдовипадкових чисел вихор Мерсенна, доступний у PHP, але він також має 32-розрядний стан. Є пропозиції щодо додавання сильної генерації випадкових чисел до PHP.[6]

Remove ads

Сильніші методи

Узагальнити
Перспектива

Існує безліч методів генерації надійних, криптографічно безпечних випадкових паролів. На платформах Unix зазвичай використовуються /dev/random і /dev/urandom або програмно, або в поєднанні з такою програмою, як makepasswd.[7] Програмісти Windows можуть використовувати функцію CryptGenRandom з Cryptographic Application Programming Interface[en]. Мова програмування Java включає клас під назвою SecureRandom. Інша можливість полягає в отриманні випадковості шляхом вимірювання якогось зовнішнього явища, наприклад визначення часу введення користувача з клавіатури.

Багато комп'ютерних систем вже мають програму (зазвичай звану «apg») для реалізації FIPS 181.[8] FIPS 181 — Automated Password Generator — описує стандартний процес перетворення випадкових бітів (з апаратного генератора випадкових чисел) у певною мірою вимовні «слова», придатні для парольної фрази.[9] Однак у 1994 році було виявлено атаку на алгоритм FIPS 181, так що зловмисник може розраховувати в середньому на злам 1 % облікових записів, які мають паролі на основі алгоритму, після пошуку лише 1,6 мільйона паролів. Це пов'язано з нерівномірністю розподілу згенерованих паролів, яку можна вирішити, використовуючи довші паролі або змінюючи алгоритм.[10][11]

Bash

Ось приклад коду, який використовує /dev/urandom для створення пароля за допомогою простої функції Bash . Ця функція приймає довжину пароля як параметр або використовує 16 за замовчуванням:

function mkpw() { LC_ALL=C tr -dc '[:graph:]' < /dev/urandom | head -c ${1:-16}; echo; }

Java

Ось зразок коду (адаптований з класу PasswordGenerator[12]), який використовує SecureRandom для генерації пароля з 10 шістнадцяткових символів:

char[] symbols = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
int length = 10;
Random random = SecureRandom.getInstanceStrong();    // as of JDK 8, this returns a SecureRandom implementation known to be strong
StringBuilder sb = new StringBuilder(length);
for (int i = 0; i < length; i++) {
    int randomIndex = random.nextInt(symbols.length);
    sb.append(symbols[randomIndex]);
}
String password = sb.toString();

JavaScript

У цьому прикладі використовується модуль Node.js Crypto для створення криптографічно захищених випадкових чисел із рівномірним розподілом.

"use strict";

const { randomInt } = require("crypto");

const secret = (length = 64) => {
  const upperCase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  const lowerCase = "abcdefghijklmnopqrstuvwxyz";
  const digits = "0123456789";
  const minus = "-";
  const underline = "_";
  const special = "!\"#$%&'*+,./:;=?@\\^`|~";
  const brackets = "[]{}()<>";
  const all = upperCase + lowerCase + digits + minus + underline + special + brackets;
  let secret = "";
  for (let index = 0; index < length; index++) secret += all.charAt(randomInt(all.length));
  return secret;
};

Perl

У цьому прикладі використовується модуль Crypt::Random::Source для пошуку джерела сильних випадкових чисел (що залежить від платформи).

use Crypt::Random::Source qw(get_strong);

while(length($out) < 15) {
    my $a = get_strong(1);
    $a =~ s/[^[:graph:]]//g;
    $out .= $a;
}
print $out;

Python

Мова Python включає клас SystemRandom, який отримує випадкові біти криптографічного рівня з /dev/urandom в Unix-подібній системі, включаючи Linux і macOS, тоді як у Windows він використовує CryptGenRandom.[13][14] Ось простий сценарій Python, який демонструє використання цього класу:

#!/usr/bin/env python3
import random, string
myrg = random.SystemRandom()
length = 10
alphabet = string.ascii_letters + string.digits # a-z A-Z 0-9
password = "".join(myrg.choice(alphabet) for _ in range(length))
print(password)

PHP

Програма PHP може відкривати та читати з /dev/urandom, якщо доступно, або викликати утиліти Microsoft.[15] Третім варіантом, якщо доступний виклик OpenSSL, є використання функції openssl_random_pseudo_bytes.[16]

Механічні методи

Ще один метод полягає у використанні фізичних пристроїв, таких як гральні кістки, для створення випадковості. Один простий спосіб зробити це — використання таблиці символів 6 на 6. Перший кидок кубика вибирає рядок у таблиці, а другий — стовпець. Так, наприклад, кидок 2, а потім кидок 4 вибере літеру «j» із таблиці перестановки нижче.[17] Для генерації символів верхнього/нижнього регістру або деяких символів можна використовувати підкидання монети, орел — велика літера, решка — мала. Якщо під час кидання кубиків була вибрана цифра, при підкиданні монети випав орел можна вибрати символ над цифрою на стандартній клавіатурі, наприклад «$» над «4» замість «4».

Remove ads

Тип і надійність згенерованого пароля

Узагальнити
Перспектива

Генератори випадкових паролів зазвичай виводять рядок символів заданої довжини. Це можуть бути окремі символи з певного набору символів, склади, призначені для створення паролів, які можна вимовити, або слова з певного списку слів для створення парольної фрази[en]. Програму можна налаштувати так, щоб кінцевий пароль відповідав місцевій політиці паролів, скажімо, завжди створюючи суміш літер, цифр і спеціальних символів. Такі політики зазвичай знижують міцність трохи нижче наступної формули, оскільки символи більше не створюються незалежно.

Надійність випадкового пароля проти певної атаки (пошук грубою силою) можна обчислити шляхом обчислення інформаційної ентропії випадкового процесу, який створив його. Якщо кожен символ у паролі створюється незалежно та з однаковою ймовірністю, ентропія в бітах визначається за формулою

де N — кількість можливих символів, а L — кількість символів у паролі. Функція log2 є логарифмом за основою 2 . H зазвичай вимірюється в бітах.[18][19]


Більше інформації Набір символів, Число символів N ...
Більше інформації Бажана ентропія пароля, H, Арабські числа ...
  1. За виключенням "пробілу".

Будь-який генератор паролів обмежений простором стану використовуваного генератора псевдовипадкових чисел, якщо він заснований на одному. Таким чином, пароль, згенерований за допомогою 32-бітного генератора, обмежений 32-бітовою ентропією, незалежно від кількості символів, які містить пароль.

Зауважте, однак, що інший тип атаки може бути успішним проти пароля, оціненого як «дуже надійний» за наведеними вище обчисленнями.

Remove ads

Програми та веб-сайти для створення паролів

В Інтернеті доступна велика кількість програм і веб-сайтів для створення паролів. Їх якість змінюється, і її важко оцінити, якщо немає чіткого опису джерела випадковості, яке використовується, і якщо вихідний код не надається для перевірки тверджень. Більше того, і, мабуть, найважливіше, передача потенційних паролів через Інтернет викликає очевидні занепокоєння щодо безпеки, особливо якщо підключення до програми сайту генерації паролів не захищено належним чином або якщо сайт якимось чином скомпрометовано. Без захищеного каналу[en] неможливо запобігти прослуховуванню, особливо через публічні мережі, такі як Інтернет. Можливим вирішенням цієї проблеми є створення пароля за допомогою мови програмування на стороні клієнта, наприклад JavaScript. Перевага цього підходу полягає в тому, що згенерований пароль залишається на клієнтському комп'ютері і не передається на зовнішній сервер або з нього.

Remove ads

Див. також

Примітки

Посилання

Loading related searches...

Wikiwand - on

Seamless Wikipedia browsing. On steroids.

Remove ads