Задать вопрос
Filimor
@Filimor
Пенсионер из Санкт-Петербурга

Есть идея. Есть прехарденинг на гитхаб. Мне нужна оценка, обсуждение. С чего начать? Куда написать?

Всем привет! Я пенсионер из Санкт-Петербурга.
Я придумал новый алгоритм аутентификации. Он позволяет иметь единый пароль-секретную последовательность действий для разных сайтов или устройств. При этом при каждой сессии аутентификации путем простейших арифметических действий пользователь будет генерировать одноразовый ключ.
Теперь я пытаюсь реализовать прототип (демонстратор возможностей) на GitHub https://github.com/NSA-Filimonov/NSA c помощью ChatGPT. На сегодняшний день программа проходит smoke, integration тесты. Нужно выходить на hardening.
Вот что у меня получилось если коротко и с юмором. Вот дверь. На ней какой-то рисунок. Цветочки, котики и т.п. Вокруг стоят хакеры и хотят взломать дверь. Ты подходишь, молча смотришь на рисунок, из палочки делаешь одноразовый ключ. Открываешь дверь - после этого рисунок мгновенно меняется. Ключ больше не подходит. Ты кидаешь его хакерам со словами - держите неудачники! Хакеры плачут, теряют свои брутфорсы и идут заниматься общественно-полезными делами. Рисунок меняется после каждого открытия. И пароль здесь - правило изготовления ключа по рисунку. Его нельзя узнать ведь ты делаешь ключ молча. Есть 60 трл дверей и им соответствующих ключей. А правило изготовления - одно. На всю жизнь хватит. Тем же алгоритмом с разными ключами ты можешь открыть все прочие двери)
  • Вопрос задан
  • 639 просмотров
Подписаться 1 Простой 48 комментариев
Помогут разобраться в теме Все курсы
  • Нетология
    1C-программист: расширенный курс
    18 месяцев
    Далее
  • Академия Эдюсон
    Python-разработчик + ИИ
    9 месяцев
    Далее
  • ProductStar × РБК
    Профессия DevOps-инженер + ИИ
    5 месяцев
    Далее
Пригласить эксперта
Ответы на вопрос 2
Daemon23RUS
@Daemon23RUS
Есть 60 трл дверей и им соответствующих ключей. А правило изготовления - одно. На всю жизнь хватит.

А есть U3S23H с производительностью 1160 ТH/s, он переберет Ваши "двери" за 0,05 секунды. А Вы про всю жизнь пишите. (Опустим алгоритмы, речь про порядки чисел)
Уверены, что выбрали верную область для получения опыта ? Ведь все о чем Вы пишите - криптография. А для ее понимания нужно как минимум академическое образование (магистратура, аспирантура по криптографии, компьютерной безопасности и прикладной математике). На GPT не выехать (можно только заехать, и то в кукурузу)
Ваша идея напоминает challenge-response аутентификацию, где по публичному "рисунку" и секретному правилу генерируется одноразовый ключ. Это отличный подход! Но безопасность зависит не только от количества "рисунков", а от сложности восстановления секретного правила по нескольким парам "рисунок - ключ", Размера секрета, Устойчивости правила к анализу (например, по 2-3 наблюдениям).
К сожалению, самодельные криптографические алгоритмы почти всегда оказываются уязвимыми, даже если кажутся сложными. Напомнило "закон Шнейера".

P.S. Подведу итог 2х дневного обсуждения:
В частности устойчивость правила к анализу, выяснилось что достаточно 2х наблюдений. Я взял пример из комментария Егор Филимонов исключил пароль, оставил только матрицу и ответ
исходный комментарий
Вот: Я пользователь. Я выбрал пароль A1+A1; A1*A1; A1-A2(abs); A1*A2 (а мог бы меньше или больше действий и ячейки самые разные) и сохранил его. Начал работу. Получил вызов:
1234

A 0123
B 4567
C 8901
D 2345

В уме я вычислил: 0+0=0; 0*0=0; 0-1=1; 0*1=0
И в поле ввода ввел полученный ключ: 0010 И получил доступ.

На следующий день прихожу, начинаю работать и получаю новый вызов:
1234

A 9876
B 5432
C 1098
D 7654

решаю: 9+9=18; 9*9=81; 9-8=1; 9*8=72
В окне ключа ввожу: 1881172 И получаю доступ.
Do you understand now?

И задал школьникам задачку на комбинаторику получил
ответ
Детали по разбиениям:0010
   [0, 0, 10] → 236,992 комбинаций
   [0, 0, 1, 0] → 48,278,656 комбинаций

Детали по разбиениям:1881172
   [18, 8, 11, 72] → 82,944 комбинаций
   [18, 81, 1, 72] → 20,352 комбинаций
   [18, 81, 17, 2] → 18,816 комбинаций
   [1, 8, 8, 11, 72] → 13,188,096 комбинаций → исключено, за пределами 1й итерации
   [1, 8, 81, 1, 72] → 3,235,968 комбинаций → исключено, за пределами 1й итерации
   [1, 8, 81, 17, 2] → 2,991,744 комбинаций → исключено, за пределами 1й итерации
   [18, 8, 1, 1, 72] → 9,707,904 комбинаций → исключено, за пределами 1й итерации
   [18, 8, 1, 17, 2] → 8,975,232 комбинаций → исключено, за пределами 1й итерации
   [18, 8, 11, 7, 2] → 16,257,024 комбинаций → исключено, за пределами 1й итерации
   [18, 81, 1, 7, 2] → 3,988,992 комбинаций → исключено, за пределами 1й итерации
   [1, 8, 8, 1, 1, 72] → 1,543,556,736 комбинаций → исключено, за пределами 1й итерации
   [1, 8, 8, 1, 17, 2] → 1,427,061,888 комбинаций → исключено, за пределами 1й итерации
   [1, 8, 8, 11, 7, 2] → 2,584,866,816 комбинаций → исключено, за пределами 1й итерации
   [1, 8, 81, 1, 7, 2] → 634,249,728 комбинаций → исключено, за пределами 1й итерации
   [18, 8, 1, 1, 7, 2] → 1,902,749,184 комбинаций → исключено, за пределами 1й итерации
   [1, 8, 8, 1, 1, 7, 2] → 302,537,120,256 комбинаций → исключено, за пределами 1й итерации

На основе этого ответа сегодня они написали программу (используя AI) и решили эту задачу,
Операции: A1+A1 → A1*A1 → A1-A2 → A1*A2
Результат
✅ Предварительная обработка завершена: 768 валидных операций.

 Проверяем разбиение: [18, 8, 11, 72]
   ❌ Нет операций для (0, 8)

 Проверяем разбиение: [18, 81, 1, 72]
   ✅ Все пары найдены. Проверяем комбинации...
✅ РЕШЕНИЕ НАЙДЕНО для разбиения [18, 81, 1, 72]
   Операции: A1+A1 → A1*A1 → A1-A2 → A1*A2
   mat1: [0, 0, 1, 0] → 0010
   mat2: [18, 81, 1, 72] → 1881172

Process finished with exit code 0

Программа на Python
def find_operations_v2():
    # Матрицы
    mat1 = [
        [0, 1, 2, 3],
        [4, 5, 6, 7],
        [8, 9, 0, 1],
        [2, 3, 4, 5]
    ]

    mat2 = [
        [9, 8, 7, 6],
        [5, 4, 3, 2],
        [1, 0, 9, 8],
        [7, 6, 5, 4]
    ]

    # Единая функция для вычисления результата операции
    def apply_op(a, b, op):
        if op == 0:
            return a + b
        elif op == 1:
            return abs(a - b)
        else:  # op == 2
            return a * b

    # Все возможные операции: (r1,c1,r2,c2,op) → результаты (res1, res2)
    from collections import defaultdict
    all_ops = []  # список всех валидных операций
    result_map = defaultdict(list)  # (res1, res2) → операции

    for r1 in range(4):
        for c1 in range(4):
            for r2 in range(4):
                for c2 in range(4):
                    for op in range(3):
                        res1 = apply_op(mat1[r1][c1], mat1[r2][c2], op)
                        res2 = apply_op(mat2[r1][c1], mat2[r2][c2], op)
                        if res1 > 81 or res2 > 81:
                            continue
                        all_ops.append((r1, c1, r2, c2, op))
                        result_map[(res1, res2)].append((r1, c1, r2, c2, op))

    print(f"✅ Предварительная обработка завершена: {len(all_ops)} валидных операций.")

    # Целевой результат для mat1
    target1 = [0, 0, 1, 0]

    # Возможные разбиения "1881172"
    possible_splits = [
        [18, 8, 11, 72],
        [18, 81, 1, 72],
        [18, 81, 17, 2]
    ]

    labels = "ABCD"

    # Перебираем все разбиения
    for target2 in possible_splits:
        print(f"\n Проверяем разбиение: {target2}")
        steps = list(zip(target1, target2))  # [(0,18), (0,8), (1,11), (0,72)] и т.д.
        candidates = []
        valid = True
        for t1, t2 in steps:
            key = (t1, t2)
            if key not in result_map:
                print(f"   ❌ Нет операций для ({t1}, {t2})")
                valid = False
                break
            candidates.append(result_map[key])
        if not valid:
            continue

        print(f"   ✅ Все пары найдены. Проверяем комбинации...")

        # Перебираем все 4-операционные последовательности
        from itertools import product
        count = 0
        for ops_seq in product(*candidates):
            count += 1
            # Проверим результаты
            res1_check = []
            res2_check = []
            for (r1, c1, r2, c2, op) in ops_seq:
                res1_check.append(apply_op(mat1[r1][c1], mat1[r2][c2], op))
                res2_check.append(apply_op(mat2[r1][c1], mat2[r2][c2], op))
            if res1_check == target1 and res2_check == target2:
                print(f"✅ РЕШЕНИЕ НАЙДЕНО для разбиения {target2}")
                ops_str = []
                for (r1, c1, r2, c2, op) in ops_seq:
                    cell1 = f"{labels[r1]}{c1+1}"
                    cell2 = f"{labels[r2]}{c2+1}"
                    op_char = "+" if op == 0 else "-" if op == 1 else "*"
                    ops_str.append(f"{cell1}{op_char}{cell2}")
                print("   Операции:", " → ".join(ops_str))
                print("   mat1:", res1_check, "→", ''.join(map(str, res1_check)))
                print("   mat2:", res2_check, "→", ''.join(map(str, res2_check)))
                return

        print(f"   ❌ Решений для этого разбиения не найдено.")

    print("\n❌ Ни одно разбиение не дало решения.")

# Запуск
find_operations_v2()


P.S.S Мы честно решили вашу первую задачу - правило восстановлено по двум парам.
Вы не оспорили решение - значит, система уязвима при 2 наблюдениях.

Новая задача с 511427 и 1845 - логически невозможна:
---1  2  3  4    1  2  3  4
--------------  ------------
A [2, 7, 0, 4]	[1, 9, 4, 2]
B [0, 3, 6, 5]	[5, 3, 0, 9]
C [0, 7, 8, 3]	[4, 6, 2, 0]
D [4, 5, 1, 2]	[1, 7, 8, 2]
-----------------------------
      511427          1845

Единственный допустимый вариант разбиения ключа 511427 -[5,11,42,7], так как:
51 > 18 ->не может быть результатом сложения/вычитания, 51 = 3×17 или 1×51 -> оба множителя >9 -> невозможно при умножении,
27 = 3×9 -> но в первой матрице нет цифры 9 -> невозможно, -> остаётся только [5,11,42,7].
Но и здесь - проблема с 42:
42 = 6×7 - единственный возможный вариант.
В первой матрице: 6 есть (B3), 7 есть (A2, C2) -> возможно B3×A2 или B3×C2.
Но во второй матрице: B3 = 0 -> операция умножения с B3 даёт 0.
А в ответе 1845 - нуля нет. -> Противоречие.
Утверждение, что правило одно - неверно.
Если это ошибка - признайте.
Если подтасовка - мы это видим.


Честный анализ требует честных данных.
У нас были одни - мы их разобрали.
Теперь Вы предлагаете другие - но они не проходят проверку на реальность.
Ответ написан
CityCat4
@CityCat4
Жил да был черный кот за углом...
Я человек ленивый, я попросил гугл (Gemini) проанализировать указанную репу.

Вот ответ гугла:
"Судя по описанию, изобрел классический велосипед с квадратными колесами. Его идея «двери с рисунком» — это обычный Challenge-Response протокол (запрос-ответ) на базе графического ключа, причем сильно уязвимый.Судя по его репозиторию, «прототип» написан на FastAPI и Redis, а логику ему генерировал ChatGPT. То есть человек без профильного образования в криптографии просто завернул старую концепцию в обертку современного веб-фреймворка.

Его «уникальная» концепция — это S/KEY (алгоритм ОPIE) и одноразовые пароли (OTP), разработанные Беллом Лампортом еще в 1981 году, смешанные с концепцией графического пароля (Graphical Passwords / Pattern-based authentication) из начала 2000-х.
Как это работает у него: Сервер дает картинку (grid_size, steps), пользователь по «секретному правилу» в голове строит маршрут (response) и отправляет его обратно. Сервер проверяет и удаляет этот challenge.
В чем «новизна»? Ни в чем. Протоколы Challenge-Response используются в каждом первом токене аутентификации (например, в банковских приложениях или Blizzard Authenticator), только там вместо рисунка — время (TOTP) или счетчик (HOTP)."

Гугл порекомендовал задать несколько вопросов :)

Вопрос А: «Как ты защищаешься от атак по сторонним каналам (Side-Channel) и плечевого серфинга?
»Если пользователь сидит в кафе, в метро или записывает экран, а камера над его плечом снимает, как он «молча смотрит на рисунок» и вводит ключ на экране — алгоритм полностью скомпрометирован. Хакеру даже не нужно брутфорсить. Он просто запишет видео ввода. В этом главная беда всех графических ключей, из-за чего от них отказываются в пользу биометрии.

Вопрос Б: «Что происходит при атаке Man-in-the-Middle (Человек посередине)?
»Он пишет: «Ты кидаешь ключ хакерам... Ключ больше не подходит».А если хакер перехватил трафик в момент отправки? Настоящая криптография (например, SRP — Secure Remote Password protocol) защищает от перехвата самого ответа в процессе. Если в системе хакер встанет между пользователем и сервером (MitM), он просто перехватит response до того, как тот долетит до сервера, подменит пакет и зайдет под видом пользователя, а пользователю вернет ошибку тайм-аута.

Вопрос В: «Каков размер энтропии твоего правила?
»Он заявляет про «60 триллионов дверей». Но человек — существо ленивое.Спросите его: если сетка (grid_size) имеет размер, например, 5х5 или 8х8, какова длина пути (steps)? Люди физически не способны запоминать сложные алгоритмы генерации путей в уме для каждой новой картинки. Они будут использовать простые правила: «проведи линию от верхнего левого котика к правому нижнему». Энтропия (хаотичность) человеческого выбора ничтожно мала. Компьютер подберет это «правило» по словарю за секунды.

И последнее (это тоже текст гугла, но я в кои-то веки с ним согласен):
То, что ChatGPT написал рабочий код на Python с интеграционными тестами и Docker-контуром, говорит лишь о том, что ChatGPT умеет настраивать Redis и FastAPI. Нейросеть не проверяла математическую стойкость алгоритма. ChatGPT просто реализовал логику: «прими данные — сверь с базой — удали из базы».

Криптографическая стойкость кода от ChatGPT равна нулю, потому что языковые модели не умеют симулировать криптоанализ.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы