Skip to content
This repository has been archived by the owner on May 18, 2024. It is now read-only.
/ pwgen Public archive

Password generator implementation in pure C inspired by pwgen

License

Notifications You must be signed in to change notification settings

allenvox/pwgen

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Password Generator (pwgen)

Техническое задание

  1. Функциональность

Реализуемый продукт — генератор паролей для терминала (командной строки). Используется для создания устойчивых ко взлому паролей, опции к которым можно задать в аргументах к программе. С помощью аргументов можно задать длину паролей в символах, получить разное их количество. Пароли могут быть состоящими как непосредственно из цифр и букв латинского алфавита, так и с использованием специальных символов (!, $, %, & и т.д.).


Сценарии использования (примеры):

Генерация одного пароля стандартной длины (8) со стандартными опциями:

$ pwgen
akbspiun


Генерация трёх паролей длиной в 10 символов со стандартными опциями:

$ pwgen 3 10
aslkrjnabs fajvmmcnal dffjasjwfg


Генерация пяти паролей длиной в 5 символов с хотя бы одной цифрой и заглавной буквой, вывод результата в столбик:

$ pwgen 5 5 -с -n -1
1H9fA
j4cNA
3D9ja
LA01B
kK5aq


Генерация трёх паролей длиной в 5 символов, основанных на хешировании строки hello, вывод в столбик:

$ pwgen 3 5 -1 -sha1 hello
aaf4c
9cf5c
1eec5


Генерация одного пароля длиной в 10 символов, используя спецсимволы и цифры:

$ pwgen 1 10 -y -n
aa2jk&js1!
  1. Формат входных данных

    $ pwgen [N] [length] [args]
    N — количество генерируемых паролей
    length — длина пароля
    args — аргументы командной строки

  2. Интерфейс
    Программа является приложением для терминала (командной строки), соответственно никакого графического интерфейса не требует.

  3. Аргументы командной строки

Аргумент Расшифровка Назначение
-h help Вывести справку и помощь по программе
-c capitalize Включить в пароль хотя бы одну букву верхнего регистра
-n numbers Включить в пароль хотя бы одну цифру
-1 one column Вывести пароли в один столбец
-y special symbols Включить в пароль хотя бы один специальный символ
-s secure Сгенерировать хаотичный пароль со всеми возможными символами (алиас флагов -n -y -c)
-H (-sha1) SHA-1 Hash Использовать хеш SHA-1 заданного сида (строки) как генератор непроизвольных знаков. Запомнив генерирующий сид, можно восстановить пароль или серию паролей.
  1. Реализация

Генерируемые пароли выводятся в терминал (командную строку) без вывода результатов в файл.

Для составления пароля используются 2 массива: массив символов char password[length] и массив целых чисел int cells[length]. В первый помещаются символы генерируемого пароля, во второй — заполнение ячеек под (1 / 0).

Перебираются введённые аргументы.

При наличии флага (опции) для генерации пароля, выбирается случайная ячейка с индексом i, для которой выполняется проверка, заполнена она или нет ( cells[i] == 1 ? ).

Если ячейка не заполнена (cells[i] = 0), в неё помещается случайный символ из алфавита заданной опции (для -c это от A до Z, для -n: от 0 до 9, для -y: от ! до +).

При отсутствии дополнительных аргументов (флагов), оставшиеся ячейки заполняются через цикл for, в котором выполняется проверка, заполнена ячейка или нет.

Если ячейка не заполнена, для неё подбирается значение из общего алфавита (для аргументов -n -c это (a-z)+(0-9)+(A-Z)).

  1. Подбор случайного значения

Значения для генерации псевдослучайных символов подбираются по генерации псевдослучайных чисел функцией getRand(), используемых для получения определённых символов из ASCII функцией getASCII(). Для специальных символов это значения от 33 до 47, для цифр - от 48 до 57, для латинских букв верхнего регистра - от 65 до 90, нижнего регистра - от 97 до 122.

#include <stdlib.h>

int getRand(int min, int max)
{
    return (double)rand() / (RAND_MAX + 1.0) * (max - min) + min;
}

char getASCII(int i)
{
    return (char)i;
}

  1. Хеширование
    При генерации паролей из заданного сида (строки) используется внешняя библиотека <sha1.h>, взятая с ресурса IETF (Internet Engineering Task Force).
Quote of Copyright

Network Working Group
Request for Comments: 3174
Category: Informational

D. Eastlake, 3rd
Motorola
P. Jones
Cisco Systems
September 2001

US Secure Hash Algorithm 1 (SHA1)

Status of this Memo

This memo provides information for the Internet community. It does not specify an Internet standard of any kind. Distribution of this memo is unlimited.

Copyright Notice

Copyright (C) The Internet Society (2001). All Rights Reserved.

Abstract

The purpose of this document is to make the SHA-1 (Secure Hash Algorithm 1) hash algorithm conveniently available to the Internet community. The United States of America has adopted the SHA-1 hash algorithm described herein as a Federal Information Processing Standard. Most of the text herein was taken by the authors from FIPS 180-1. Only the C code implementation is "original".

Алгоритм:

  1. Получение количества паролей, длины паролей и генерирующей строки (сида) в аргументах: $ pwgen <N> <length> -sha1 <seed>
  2. Создание массива хешей по количеству паролей: char hashed[N][SHA1-LENGTH]
  3. Получение полного хеша SHA1 из строки: hashed[0] = SHA1(seed)
  4. Генерация последующих полных хешей, где hashed[k] = SHA1(hashed[k-1])
  5. Вывод первых length символов для пароля от каждого хеша:
for(int k = 0; k < N; k++) {
 for(int c = 0; c < length; c++) {
   printf(hashed[k][c]);
 }
 printf("\n");
}

Таким образом, при утере пароля и количества символов в нём, пользователь сможет восстановить пароль/серию паролей, используя свою генерирующую строку.

Пример использования:

— Сегодня я сделаю себе новые пароли! Пусть они будут сгенерированы в честь моего дня рождения. Символов 5 будет достаточно, по количеству тоже 5.

$ pwgen 5 5 -sha1 25.01.2003
a675d
ee036
f51ad
1e977
dc5b6

*one eternity later*

— Кажется, я совсем забыл свои пароли... Помню только, что генерировал их по дате своего рождения. Попробую сгенерировать ещё раз, возьму побольше длину, а там вспомню.

$ pwgen 5 8 -sha1 25.01.2003
a675d77d
ee036500
f51adb89
1e97768e
dc5b6047

– Как замечательно! Помню, что в моём первом пароле точно не было двух семёрок, значит я генерировал пароли длиной по 5 символов!

The end.


  1. Guards (проверки, используемые для предотвращения ошибок)
Условие Назначение Результат
argс - 1 > length Если количество аргументов больше количества доступных символов в пароле Ошибка о малой длине пароля
argc = 2
argv[1] = "-s"
length < 3
Если аргумент является алиасом для нескольких аргументов
(-s для -n -y -c)
Ошибка о малой длине пароля