Случайный пароль
От: TailWind  
Дата: 19.05.23 05:57
Оценка:
Как сделать случайный пароль на 24 символа?
И потом ещё один такой же

Нужно чтобы между символами и паролями не было математической зависимости

То есть rand(), rand(), rand(), rand() не подходит

Единственное, что мне пришло в голову rand(GetTickCount())
Но этого мало. А дальше то как?
Re: Случайный пароль
От: Carc Россия http://www.amlpages.com/home.php
Дата: 19.05.23 06:08
Оценка: -1
Здравствуйте, TailWind, Вы писали:

TW>Как сделать случайный пароль на 24 символа?

TW>И потом ещё один такой же

TW>Нужно чтобы между символами и паролями не было математической зависимости


TW>То есть rand(), rand(), rand(), rand() не подходит


TW>Единственное, что мне пришло в голову rand(GetTickCount())

TW>Но этого мало. А дальше то как?
void gen_random(TCHAR *s
    , const int len
    , const TCHAR* pszSymbols
    ,  const UINT nSizeSymbols) 
{
    for (int i = 0; i < len; ++i) {
        //const TCHAR sz== alphanum[rand() % (nSizeSymbols - 1)]
        const TCHAR sz = *(pszSymbols+ (rand() % (nSizeSymbols - 1)));
        s[i] =sz;
    }

    s[len] = 0;
}

void gen_random(TCHAR *s, const int len, const bool bSpecialSymbols)
{
    const TCHAR alphanum[] =
        TEXT("0123456789")
        TEXT("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
        TEXT("abcdefghijklmnopqrstuvwxyz");

    const TCHAR szSpec[]=TEXT("!@#$%^&*()_-\\/|\"'~");

    typedef std::vector<TCHAR> V;
    V v;
    UINT nSize=ARRAYSIZE(alphanum);
    if (bSpecialSymbols)
        nSize += ARRAYSIZE(szSpec);

    nSize += 1;
    v.reserve(nSize);

    std::back_insert_iterator<V> bi(v);
    std::copy(alphanum,alphanum+ARRAYSIZE(alphanum),bi);
    const int nnnsdfs=v.size();
    if (bSpecialSymbols)
        std::copy(szSpec, szSpec+ARRAYSIZE(szSpec),bi);

    const int nsd=v.size();
    
    gen_random(s, len, &v[0],v.size());
}

CString Generate(const UINT nMaxLen,const bool bUseSpecSymbols)
{
    ASSERT(nMaxLen > 0);
    if (0 == nMaxLen)
        return TEXT("");

    enum {MAX_LEN=1000};
    if (nMaxLen > MAX_LEN) {
        ASSERT(FALSE);
        return TEXT("");
    };

    TCHAR sz[MAX_LEN+1];
    gen_random(sz,nMaxLen,bUseSpecSymbols);
    ASSERT(!IsBadStringPtr(&sz[0],INFINITE));

    CString s(sz);
    UINT nTryCount=0;
    enum {MAX_TRY_COUNT=10};
    while (nTryCount < MAX_TRY_COUNT) {
        if (s.GetLength() == nMaxLen)
            break;

        ++nTryCount;
        s=Generate(nMaxLen,bUseSpecSymbols);
    };

    return s;
}
Aml Pages Home
Re[2]: Случайный пароль
От: TailWind  
Дата: 19.05.23 06:20
Оценка: +1 -2
Это всё равно основано на rand()

Значит любой человек, используя disassembler сможет восстановить этот алгоритм и предсказывать ваши пароли
Re: Случайный пароль
От: so5team https://stiffstream.com
Дата: 19.05.23 07:18
Оценка: +2
Здравствуйте, TailWind, Вы писали:

TW>Нужно чтобы между символами и паролями не было математической зависимости


TW>То есть rand(), rand(), rand(), rand() не подходит


Не специалист, но слышал о том, что копать нужно в сторону CSPRNG. По этой ссылке в Wikipedia есть названия конкретных реализаций, вроде CryptGenRandom для Windows или /dev/urandom для Linux.
Re: Случайный пароль
От: sergii.p  
Дата: 19.05.23 07:28
Оценка: +1
Здравствуйте, TailWind, Вы писали:

TW>Как сделать случайный пароль на 24 символа?

TW>И потом ещё один такой же

TW>Нужно чтобы между символами и паролями не было математической зависимости


вроде стандартный подход: попросить у пользователя случайную последовательность (мышкой поводить, набрать абракадабру на клавиатуре). И её уже использовать как затравку для rand.
Re: Случайный пароль
От: ononim  
Дата: 19.05.23 07:59
Оценка:
https://stackoverflow.com/questions/7560114/random-number-c-in-some-range
Как много веселых ребят, и все делают велосипед...
Re: Случайный пароль
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.05.23 10:40
Оценка: +1
Здравствуйте, TailWind, Вы писали:

TW>Как сделать случайный пароль на 24 символа?

TW>И потом ещё один такой же

TW>Нужно чтобы между символами и паролями не было математической зависимости


Когда говоришь о "случайных значениях", надо в первую очередь определить, требуется ли максимально непредсказуемая случайность, или нужно таки получить воспроизводимость.
Раз речь о паролях — то скорее первое.
Тогда второе это какая платформа.
В современных Unix типа Linux, MacOS самый простой и надёжный вариант это открыть /dev/urandom, прочитать нужное количество байт из него (они будут равномерно распределёнными значениями от 0 до 255, независимые друг от друга) и из них сгенерировать что нужно.
Для винды мне подсказывают про CryptGetRandom(), но я не проверял.

TW>То есть rand(), rand(), rand(), rand() не подходит


TW>Единственное, что мне пришло в голову rand(GetTickCount())

TW>Но этого мало. А дальше то как?

И какой набор символов?
Вот что-то вроде подобного я бы сделал для Linux

static const char PASSWORD_CHARS[] = "0123456789abcdefghijklmnopqrstuvwxyz"; // подправить по вкусу
static size_t PASSWORD_CHARS_COUNT = sizeof(PASSWORD_CHARS) - 1;

static inline uint64_t getOneNumber(int fd) {
  uint64_t n;
  if (read(fd, &n, sizeof n) != sizeof n) { abort(); }
  return n;
}

void gen_password(char* obuf, size_t osize) { // NB не терминирует NUL
  int fd = open("/dev/urandom", O_RDONLY, 0); if (fd == -1) { abort(); }
  for (size_t idx = 0; idx < osize; ++idx) {
    uint64_t n = getOneNumber(fd);
    obuf[idx] = PASSWORD_CHARS[n % PASSWORD_CHARS_COUNT];
  }
  close(fd);
}


Топорно (целых 8 байт входа на один символ выхода) но работает.
The God is real, unless declared integer.
Re[2]: Случайный пароль
От: TailWind  
Дата: 19.05.23 11:00
Оценка:
SP>вроде стандартный подход: попросить у пользователя случайную последовательность (мышкой поводить, набрать абракадабру на клавиатуре). И её уже использовать как затравку для rand.

Не очень понятно как из этого сделать равномерное распределение
Проблема с rand() в том, что она повторяется каждые 3fff байт
Имея на руках программу можно сгенерировать всего 3fff комбинаций пароля.
А это перебором можно подобрать
Отредактировано 19.05.2023 11:03 TailWind . Предыдущая версия .
Re[2]: Случайный пароль
От: TailWind  
Дата: 19.05.23 11:01
Оценка:
N>требуется ли максимально непредсказуемая случайность
Да. Винда. И линукс под Wine

Нужно сгенерировать два 64-bit пароля

Закодировать проблем нет. Нужна концепция
Отредактировано 19.05.2023 11:03 TailWind . Предыдущая версия .
Re[2]: Случайный пароль
От: so5team https://stiffstream.com
Дата: 19.05.23 11:17
Оценка:
Здравствуйте, netch80, Вы писали:

N>Топорно (целых 8 байт входа на один символ выхода) но работает.


А разве /dev/urandom нельзя читать побайтово?
Re[3]: Случайный пароль
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.05.23 11:25
Оценка: 13 (2)
Здравствуйте, so5team, Вы писали:

N>>Топорно (целых 8 байт входа на один символ выхода) но работает.

S>А разве /dev/urandom нельзя читать побайтово?

Можно, но если, например, 36 символов возможно в пароле (26 английских букв и 10 цифр), а мы берём по 1 байту входа на символ выхода... 256 делим на 36, в остатке 4 — это значит, что первые 4 в наборе будут генерироваться чаще, чем остальные (на 1/7 чаще).
Эффект не сильно большой, но для серьёзной секьюрити может влиять.
Если больше набор (до 70 символов можно позволить), эффект ещё сильнее, типа 1/3 разницы.
А если делить на входе числа от 0 до 2**64-1, эффект становится неизмеримо малым.
Это то, почему std::hash()() должен выдавать size_t (я удивлён, что не uintmax_t, но, видимо, сочли достаточным).
Не-топорно требует цепочечного деления или base32/base64/etc. — облом такое кодить без нужды
The God is real, unless declared integer.
Re[3]: Случайный пароль
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 19.05.23 11:30
Оценка:
Здравствуйте, TailWind, Вы писали:

TW>Закодировать проблем нет. Нужна концепция


Тогда концепция сводится к очень простой фразе: надо применить тот генератор случайных чисел, который предназначен для криптографии, а не тот, что для математических экспериментов типа метода Монте-Карло, когда важна воспроизводимость последовательности.
Потому что rand(), random(), lrand48(), Xorshift, вихрь Мерсенна и прочие из подобной группы они все именно для математических экспериментов. И они, соответственно, не годятся.

(Недавно в FB Шон Таунсенд пробегался по этому и по любителям применять дефолтные генераторы для нужд криптографии. Говорит, что вообще сейчас все стандартные библиотеки надо переделывать на непресказуемо случайные генераторы с криптографической надёжностью, чтобы, наоборот, предсказуемость была только следствием явного решения, а не наоборот. Мысль не нова, но столь чётко оформленной я её раньше не видел.)
The God is real, unless declared integer.
Re: Случайный пароль
От: vsb Казахстан  
Дата: 19.05.23 14:33
Оценка:
base64 </dev/random|head -c 24
Отредактировано 19.05.2023 14:37 vsb . Предыдущая версия .
Re[4]: Случайный пароль
От: vsb Казахстан  
Дата: 19.05.23 14:41
Оценка:
Здравствуйте, netch80, Вы писали:

N>Можно, но если, например, 36 символов возможно в пароле (26 английских букв и 10 цифр), а мы берём по 1 байту входа на символ выхода... 256 делим на 36, в остатке 4 — это значит, что первые 4 в наборе будут генерироваться чаще, чем остальные (на 1/7 чаще).

N>Эффект не сильно большой, но для серьёзной секьюрити может влиять.
N>Если больше набор (до 70 символов можно позволить), эффект ещё сильнее, типа 1/3 разницы.
N>А если делить на входе числа от 0 до 2**64-1, эффект становится неизмеримо малым.
N>Это то, почему std::hash()() должен выдавать size_t (я удивлён, что не uintmax_t, но, видимо, сочли достаточным).
N>Не-топорно требует цепочечного деления или base32/base64/etc. — облом такое кодить без нужды

Берёшь остаток от деления на 64. Если результат меньше 36, возвращаешь его. Иначе генерируешь новое число. Способ простой и даёт равномерное распределение.

Хотя для пароля проще взять 32 или 64 разных символа. Тогда заморачиваться не надо.
Отредактировано 19.05.2023 14:42 vsb . Предыдущая версия .
Re: Случайный пароль
От: mike_rs Россия  
Дата: 19.05.23 14:54
Оценка:
Здравствуйте, TailWind, Вы писали:

TW>Единственное, что мне пришло в голову rand(GetTickCount())

TW>Но этого мало. А дальше то как?

srand(time(null)), затем rand, rand, rand ....
потом для второго пароля аналогично
srand(time(null)), затем rand, rand, rand ....

без знания времени генерации восстановить не получится
Re[2]: Случайный пароль
От: vsb Казахстан  
Дата: 19.05.23 16:57
Оценка: +1 -1
Здравствуйте, mike_rs, Вы писали:

_>без знания времени генерации восстановить не получится


Перебрать возможные значения time() может быть куда быстрей, чем перебрать пароли. time() возвращает время в секундах. Это всего лишь 31.5 млн вариантов, если известен хотя бы год. А уж если можно вывести точное время, к примеру по времени модификации какого-то файла, то там уже безопасность можно считать нулевая.

В общем я бы сказал, что это ОЧЕНЬ плохой вариант, сорри.

Надо использовать /dev/random или аналог в винде.
Re: Случайный пароль
От: Alexander_S_U https://github.com/alexanders-code/cmdxmlinstaller
Дата: 19.05.23 19:48
Оценка:
Здравствуйте, TailWind, Вы писали:

TW>Как сделать случайный пароль на 24 символа?

TW>И потом ещё один такой же
...
Может воспользоваться функциями для генерации псевдослучайных значений из <random>.
Например Равномерное распределение
https://github.com/alexanders-code/cmdxmlinstaller
Re[3]: Случайный пароль
От: Dair Россия  
Дата: 19.05.23 19:54
Оценка:
Здравствуйте, TailWind, Вы писали:

TW>Это всё равно основано на rand()

TW>Значит любой человек, используя disassembler сможет восстановить этот алгоритм и предсказывать ваши пароли

Серьёзно?

Re: Случайный пароль
От: PM  
Дата: 19.05.23 20:45
Оценка: +1
Здравствуйте, TailWind, Вы писали:

TW>Как сделать случайный пароль на 24 символа?

TW>И потом ещё один такой же

TW>Нужно чтобы между символами и паролями не было математической зависимости


Минимально модифицированный пример из https://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
#include <iostream>
#include <random>
 
int main()
{
    std::random_device rd;  // a seed source for the random number engine
    std::mt19937 gen(rd()); // mersenne_twister_engine seeded with rd()
    std::uniform_int_distribution<char> distrib('0', 'z');
 
    // Use distrib to transform the random int
    // generated by gen into an char in ['0' ... 'z']
    for (int n = 0; n != 24; ++n)
        std::cout << distrib(gen);
    std::cout << '\n';
}


На https://godbolt.org/z/E9K5TWoYo выдает что-нибудь вроде

Program returned: 0
Program stdout
xZHQHnCDrgMDjI6r=rQeLtE8

Re: Случайный пароль
От: PM  
Дата: 19.05.23 20:54
Оценка:
Здравствуйте, TailWind, Вы писали:

TW>Как сделать случайный пароль на 24 символа?

TW>И потом ещё один такой же

TW>Нужно чтобы между символами и паролями не было математической зависимости


Минимально модифицированный пример из https://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
#include <iostream>
#include <random>
 
int main()
{
    std::random_device rd;  // a seed source for the random number engine
    std::mt19937 gen(rd()); // mersenne_twister_engine seeded with rd()
    std::uniform_int_distribution<char> distrib('0', 'z');
 
    // Use distrib to transform the random int
    // generated by gen into an char in ['0' ... 'z']
    for (int n = 0; n != 24; ++n)
        std::cout << distrib(gen);
    std::cout << '\n';
}


На https://godbolt.org/z/E9K5TWoYo выдает что-нибудь вроде

Program returned: 0
Program stdout
xZHQHnCDrgMDjI6r=rQeLtE8

Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.