- Сравнивать симметричное и асимметричное шифрование и объяснять проблему распределения ключей
- Строить ключи RSA на маленьких числах, шифровать, расшифровывать и подписывать
- Объяснять свойства хешей и правильное хранение паролей
- Распознавать основные атаки и выбирать защиту от них
Когда Лейла платит в банковском приложении, данные проходят через десятки чужих устройств, но никто не может прочитать или изменить сумму, а банк уверен, что запрос пришёл именно от Лейлы. Это обеспечивает криптография. Она служит четырём целям: конфиденциальность (посторонние не прочитают), целостность (изменения обнаруживаются), аутентичность (известно, кто отправил) и неотказуемость (отправитель не сможет потом сказать «это был не я»).
Симметричное шифрование
- M, Cоткрытый текст и шифртекст
- Kодин и тот же секретный ключ у обеих сторон
- E, Dалгоритмы шифрования и расшифрования (например, AES)
Принцип Керкгоффса: алгоритм может быть известен всем, безопасность должна держаться только на секретности ключа.
Современный стандарт — AES (ключи 128, 192 или 256 бит): он очень быстр и поддерживается процессорами аппаратно. У 128-битного ключа 2¹²⁸ ≈ 3,4 · 10³⁸ вариантов — перебрать их практически невозможно. Настоящая проблема в другом: как передать ключ? Каждой паре из n человек нужен свой ключ — n(n − 1)/2 ключей, для 1000 пользователей это 499 500. К тому же впервые передать ключ по незащищённому каналу нельзя.
Асимметричная криптография: Диффи — Хеллман и RSA
В асимметричной криптографии у каждого пользователя два ключа: открытый, который дают всем, и закрытый, который никому не показывают. Зашифрованное открытым ключом может расшифровать только закрытый. Это опирается на математические операции «легко в одну сторону, трудно обратно»: перемножить два больших простых числа легко, а разложить произведение на множители очень трудно; вычислить gᵃ mod p легко, а найти a (дискретный логарифм) трудно.
- p, gобщеизвестные простое число и основание
- a, bсекретные числа сторон
- sобщий секрет — никогда не передаётся по сети
Обмен ключами Диффи — Хеллмана: подслушивающий видит p, g, A и B, но чтобы получить s, ему нужно решить задачу дискретного логарифма.
p = 23, g = 5. Секрет Айсель a = 6, Мурада — b = 15. Найди открытые числа и общий ключ.
Показать решениеСкрыть решение
A = 5⁶ = (5²)³ ≡ 2³ = 8.
B = 5¹⁵ = 5¹² · 5³; 5¹² = (5⁶)² ≡ 64 ≡ 18; 5³ = 125 ≡ 10; 18 · 10 = 180 ≡ 19.
Айсель: s = 19⁶; 19 ≡ −4, (−4)⁶ = 4096 = 23 · 178 + 2 → s = 2.
Мурад: s = 8¹⁵ = 2⁴⁵; 2¹¹ = 2048 = 23 · 89 + 1 ≡ 1, значит 2⁴⁵ = (2¹¹)⁴ · 2 ≡ 2 ✓.
Оба получили один и тот же ключ, хотя число 2 ни разу не появилось в сети.
- p, qдва больших секретных простых числа (на практике ≈ 1024 бита каждое)
- (n, e)открытый ключ
- dзакрытый ключ: обратный к e по модулю φ(n)
- m, cсообщение (0 ≤ m < n) и шифртекст
RSA (Ривест, Шамир, Адлеман, 1977). Чтобы найти d, нужно φ(n), а для него — множители n: безопасность держится на трудности разложения на множители.
p = 3, q = 11, e = 3. Построй ключи, зашифруй и расшифруй сообщение m = 4, затем подпиши его и проверь подпись.
Показать решениеСкрыть решение
d: 3d ≡ 1 (mod 20) → d = 7 (3 · 7 = 21 = 20 + 1). Открытый ключ (33, 3), закрытый — 7.
Шифрование: c = 4³ = 64 mod 33 = 31.
Расшифрование: 31⁷ mod 33; 31 ≡ −2 → (−2)⁷ = −128; 128 = 3 · 33 + 29 → −128 ≡ −29 ≡ 4 ✓.
Подпись (закрытым ключом): s = 4⁷ = 16 384 = 33 · 496 + 16 → s = 16.
Проверка (открытым ключом): 16³ = 4096 = 33 · 124 + 4 → 4 = m ✓ — подпись верна.
p, g = 23, 5
a, b = 6, 15
A, B = pow(g, a, p), pow(g, b, p)
print('DH public:', A, B, '| shared:', pow(B, a, p), pow(A, b, p))
p, q, e = 3, 11, 3
n, phi = p * q, (p - 1) * (q - 1)
d = pow(e, -1, phi)
m = 4
c = pow(m, e, n)
print('RSA n =', n, 'phi =', phi, 'd =', d)
print('encrypt', m, '->', c, '| decrypt ->', pow(c, d, n))
s = pow(m, d, n)
print('signature', s, '| verify ->', pow(s, e, n))▸ Ожидаемый результат
DH public: 8 19 | shared: 2 2 RSA n = 33 phi = 20 d = 7 encrypt 4 -> 31 | decrypt -> 4 signature 16 | verify -> 4
pow(x, k, n) — быстрое возведение в степень по модулю (повторным возведением в квадрат, O(log k) умножений), а pow(e, -1, phi) находит обратный по модулю расширенным алгоритмом Евклида. Оба примера подтверждают ручные расчёты.Хеш-функции и цифровые подписи
Криптографический хеш (например, SHA-256) превращает данные любой длины в «отпечаток» фиксированной длины (256 бит). Требования: каждый раз один и тот же результат; по хешу нельзя восстановить данные (односторонность); найти два разных входа с одинаковым хешем практически невозможно (стойкость к коллизиям); изменение одного бита меняет примерно половину битов хеша (лавинный эффект). Хеш — не шифрование: у него нет ключа, и его нельзя обратить.
import hashlib, math
for text in ['Educora', 'educora', 'Educora!']:
print(text, hashlib.sha256(text.encode()).hexdigest()[:16])
rate = 10 ** 10
for name, n, length in [('8 lowercase', 26, 8), ('12 mixed', 94, 12)]:
bits = length * math.log2(n)
seconds = n ** length / rate
print(name, '|', round(bits, 1), 'bits |', f'{seconds:.3g}', 'seconds')▸ Ожидаемый результат
Educora b3dbb4d80128c71a educora 48ecb7c2aeec01dc Educora! 836636e98b18e97a 8 lowercase | 37.6 bits | 20.9 seconds 12 mixed | 78.7 bits | 4.76e+13 seconds
- Hэнтропия случайного пароля, бит
- Lдлина пароля
- Nразмер алфавита (26 строчных букв, 94 печатных символа)
Каждый дополнительный бит вдвое удлиняет перебор. Формула верна только для действительно случайных паролей: пароли вроде «Baku2026!» быстро находятся атаками по словарю.
Пароли нельзя хранить ни открытым текстом, ни простым SHA-256: сервер выдаёт каждому пользователю случайную соль и хеширует пароль намеренно медленной функцией — Argon2, bcrypt, scrypt или PBKDF2. Соль не даёт одинаковым паролям давать одинаковые хеши и обесценивает заранее вычисленные таблицы, а медлительность мешает миллиардам быстрых попыток. Цифровая подпись устроена так: отправитель подписывает хеш сообщения своим закрытым ключом, а любой проверяет её открытым ключом отправителя. Кому принадлежит открытый ключ, подтверждает сертификат — документ, подписанный доверенным центром (CA).
Атаки и защита
| Атака | Суть | Защита |
|---|---|---|
| Фишинг | поддельный сайт или письмо выманивает пароль | двухфакторная аутентификация, проверка адреса, ключи доступа (passkeys) |
| SQL-инъекция | вводимый текст становится частью запроса | параметризованные запросы, ORM |
| XSS | в чужую страницу внедряется скрипт | экранирование вывода, Content-Security-Policy |
| Человек посередине (MITM) | трафик тайно читают или подменяют | TLS, проверка сертификатов |
| Подбор пароля | перебор и атаки по словарю | длинные случайные пароли, ограничение попыток, медленный хеш с солью |
| Программы-вымогатели | шифрует файлы и требует выкуп | офлайн-резервные копии, обновления, минимальные права |
-- the program glues user input into the query:
-- WHERE email = '<input>'
-- the attacker types: x' OR '1'='1
SELECT COUNT(*) AS leaked_rows
FROM students
WHERE email = 'x' OR '1'='1';▸ Ожидаемый результат
leaked_rows 12
OR '1'='1' всегда истинно, утекают все 12 студентов. В параметризованном запросе (WHERE email = ?) тот же ввод сравнивается как обычный текст и возвращает 0 строк.Главное
- Симметричное шифрование (AES) быстрое, но есть проблема распределения ключей: n людям нужно n(n − 1)/2 ключей.
- Диффи — Хеллман создаёт общий ключ, не пересылая его: s = gᵃᵇ mod p.
- RSA: n = pq, ed ≡ 1 (mod φ), c = mᵉ mod n, m = cᵈ mod n; подпись s = mᵈ, проверка sᵉ = m.
- Хеш односторонний и стойкий к коллизиям; пароли хранят с солью и медленным хешем (Argon2, bcrypt).
- Параметризованные запросы останавливают SQL-инъекции, TLS — атаки «человек посередине»; не пиши криптографию сам.
Проверь себя
Вопросов: 10. Каждый правильный ответ приносит XP.