✅ Good
Основи криптографії¶
Криптографія — це наука про захист інформації за допомогою математичних алгоритмів. Без криптографії неможливий безпечний інтернет: банкінг, HTTPS, SSH, VPN — все базується на цих принципах.
Чому це важливо для UMTC?
Що забезпечує криптографія?¶
flowchart TB
subgraph goals["Цілі криптографії"]
CONF["🔒 Конфіденційність<br/>Тільки авторизовані читають"]
INTEG["✅ Цілісність<br/>Дані не змінено"]
AUTH["🪪 Автентичність<br/>Підтвердження особи"]
NONREP["📝 Неспростовність<br/>Не можна заперечити"]
end
style CONF fill:#dbeafe
style INTEG fill:#d1fae5
style AUTH fill:#fef3c7
style NONREP fill:#fee2e2flowchart LR
PLAIN["Plaintext<br/>Hello"] --> ENC["🔐 Encrypt"]
KEY1["🔑 Key"] --> ENC
ENC --> CIPHER["Ciphertext<br/>x7Gh2k..."]
CIPHER --> DEC["🔓 Decrypt"]
KEY2["🔑 Key"] --> DEC
DEC --> PLAIN2["Plaintext<br/>Hello"]
style CIPHER fill:#fef3c7Симетричне шифрування¶
Принцип роботи¶
Один ключ для шифрування та дешифрування.
sequenceDiagram
participant Alice as 👩 Alice
participant Network as 🌐 Мережа
participant Bob as 👨 Bob
Note over Alice: Plaintext: "Secret"
Alice->>Alice: Encrypt(key="password123")
Note over Alice: Ciphertext: "x7Gh2kL9..."
Alice->>Network: Передача шифротексту
Network->>Bob: Отримання шифротексту
Bob->>Bob: Decrypt(key="password123")
Note over Bob: Plaintext: "Secret"
Note over Alice,Bob: ⚠️ Проблема: Як безпечно передати ключ?
Головна проблема
Обидві сторони повинні мати однаковий ключ. Як його передати безпечно? Якщо ключ перехоплять — все шифрування марне.
Алгоритми¶
| Алгоритм | Розмір ключа | Статус | Примітки |
|---|---|---|---|
| DES | 56 біт | Небезпечний | Не використовувати! |
| 3DES | 168 біт | Застарілий | Повільний |
| AES-128 | 128 біт | Безпечний | Стандарт |
| AES-256 | 256 біт | Дуже безпечний | Рекомендовано |
| ChaCha20 | 256 біт | Безпечний | Швидкий на CPU без AES-NI |
Режими шифрування (Block Cipher Modes)¶
flowchart TB
subgraph ecb["❌ ECB — НЕ ВИКОРИСТОВУВАТИ"]
direction LR
B1["Block1"] --> E1["Encrypt"] --> C1["Cipher1"]
B2["Block1"] --> E2["Encrypt"] --> C2["Cipher1"]
B3["Block2"] --> E3["Encrypt"] --> C3["Cipher2"]
Note1["Однакові блоки = однаковий шифротекст!"]
end
subgraph cbc["⚠️ CBC — Краще"]
direction LR
IV["IV"] --> XOR1["XOR"]
BL1["Block1"] --> XOR1
XOR1 --> EN1["Encrypt"] --> CI1["Cipher1"]
CI1 --> XOR2["XOR"]
BL2["Block2"] --> XOR2
XOR2 --> EN2["Encrypt"] --> CI2["Cipher2"]
end
subgraph gcm["✅ GCM — РЕКОМЕНДОВАНО"]
direction TB
G1["• Authenticated encryption"]
G2["• Паралельне шифрування"]
G3["• Authentication tag"]
end
style ecb fill:#fee2e2
style cbc fill:#fef3c7
style gcm fill:#d1fae5| Режим | Переваги | Недоліки |
|---|---|---|
| ECB | Простий | Видно паттерни — небезпечний! |
| CBC | Безпечний з IV | Послідовний, вразливий до padding oracle |
| GCM | AEAD, швидкий | Потребує унікальний nonce |
Рекомендація
Завжди використовуйте **AES-256-GCM** — це "золотий стандарт" для сучасного шифрування.
Приклад з OpenSSL¶
# Шифрування файлу з AES-256-CBC
openssl enc -aes-256-cbc -salt -pbkdf2 -in secret.txt -out secret.enc
# Запитає пароль
# Дешифрування
openssl enc -aes-256-cbc -d -pbkdf2 -in secret.enc -out decrypted.txt
# AES-256-GCM (рекомендовано)
openssl enc -aes-256-gcm -salt -pbkdf2 -in file.txt -out file.enc
Асиметричне шифрування¶
Принцип роботи¶
Пара ключів: публічний (public) та приватний (private).
flowchart TB
subgraph keygen["Генерація ключів"]
GEN["🔧 Generate"] --> PUB["🔓 Public Key<br/>Можна поширювати"]
GEN --> PRIV["🔑 Private Key<br/>СЕКРЕТНИЙ!"]
end
style PUB fill:#d1fae5
style PRIV fill:#fee2e2sequenceDiagram
participant Alice as 👩 Alice
participant Public as 🌐 Public
participant Bob as 👨 Bob
Bob->>Public: Публікує Public Key
Alice->>Public: Отримує Bob's Public Key
Alice->>Alice: Encrypt(message, Bob's Public Key)
Alice->>Bob: Шифротекст
Bob->>Bob: Decrypt(message, Bob's Private Key)
Note over Bob: Тільки Bob може розшифрувати!
Аналогія
Публічний ключ — це **замок**, який кожен може замкнути. Приватний ключ — це **ключ від замка**, який є тільки у власника.
Алгоритми¶
| Алгоритм | Тип | Розмір ключа | Використання |
|---|---|---|---|
| RSA | Шифрування + підпис | 2048-4096 біт | TLS, SSH, GPG |
| ECDSA | Підпис | 256-384 біт | TLS, Bitcoin |
| Ed25519 | Підпис | 256 біт | SSH, сучасний стандарт |
| X25519 | Key exchange | 256 біт | TLS 1.3 |
RSA¶
┌─────────────────────────────────────────────────────────────────┐
│ RSA — найпоширеніший алгоритм │
│ │
│ Безпека базується на складності факторизації великих чисел │
│ │
│ n = p × q (де p, q — великі прості числа) │
│ │
│ Знаючи n, дуже важко знайти p і q │
│ │
│ Рекомендовані розміри: │
│ • 2048 біт — мінімум │
│ • 3072 біт — рекомендовано │
│ • 4096 біт — для довгострокового захисту │
└─────────────────────────────────────────────────────────────────┘
Ed25519¶
┌─────────────────────────────────────────────────────────────────┐
│ Ed25519 — сучасний алгоритм підпису │
│ │
│ Переваги: │
│ • Коротші ключі (256 біт ≈ RSA 3000 біт) │
│ • Швидший за RSA │
│ • Захищений від timing attacks │
│ • Простіша реалізація (менше помилок) │
│ │
│ Рекомендовано для SSH: │
│ ssh-keygen -t ed25519 │
└─────────────────────────────────────────────────────────────────┘
Приклад з OpenSSL¶
# Генерація RSA ключів
openssl genrsa -out private.pem 4096
openssl rsa -in private.pem -pubout -out public.pem
# Шифрування публічним ключем
openssl rsautl -encrypt -inkey public.pem -pubin -in message.txt -out encrypted.bin
# Дешифрування приватним ключем
openssl rsautl -decrypt -inkey private.pem -in encrypted.bin -out decrypted.txt
# Генерація Ed25519 (для SSH)
ssh-keygen -t ed25519 -C "your@email.com"
Хеш-функції¶
Що таке хеш?¶
Хеш-функція перетворює дані будь-якого розміру в фіксований "відбиток".
┌─────────────────────────────────────────────────────────────────┐
│ Властивості криптографічного хешу: │
│ │
│ 1. Детермінований │
│ Однаковий вхід → однаковий хеш (завжди) │
│ │
│ 2. Швидкий │
│ Обчислення займає мілісекунди │
│ │
│ 3. Односторонній │
│ Неможливо відновити вхідні дані з хешу │
│ │
│ 4. Collision resistant │
│ Практично неможливо знайти два різних входи з однаковим │
│ хешем │
│ │
│ 5. Avalanche effect │
│ Маленька зміна входу → повністю інший хеш │
└─────────────────────────────────────────────────────────────────┘
Avalanche Effect¶
$ echo -n "Hello" | sha256sum
185f8db32271fe25f561a6fc938b2e264306ec304eda518007d1764826381969
$ echo -n "hello" | sha256sum
2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
# Одна буква змінилася — хеш повністю інший!
Алгоритми¶
| Алгоритм | Розмір | Статус | Використання |
|---|---|---|---|
| MD5 | 128 біт | НЕБЕЗПЕЧНИЙ | Тільки checksums |
| SHA-1 | 160 біт | НЕБЕЗПЕЧНИЙ | Не використовувати |
| SHA-256 | 256 біт | Безпечний | Стандарт |
| SHA-384 | 384 біт | Безпечний | Високий рівень |
| SHA-512 | 512 біт | Безпечний | Максимальний рівень |
| SHA-3 | 256/512 біт | Безпечний | Новий стандарт |
| BLAKE2 | 256/512 біт | Безпечний | Швидший за SHA |
Чому MD5 та SHA-1 небезпечні?¶
┌─────────────────────────────────────────────────────────────────┐
│ Collision Attack — знайти два різних файли з однаковим хешем │
│ │
│ MD5: Collision знайдено за секунди (2004) │
│ SHA-1: Collision знайдено (2017, Google "SHAttered") │
│ │
│ Атакуючий може створити підроблений файл з тим самим хешем! │
│ │
│ НІКОЛИ не використовувати для: │
│ • Паролів │
│ • Цифрових підписів │
│ • Сертифікатів │
└─────────────────────────────────────────────────────────────────┘
Приклади з Linux¶
# Обчислити хеш файлу
sha256sum file.txt
# e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 file.txt
# Перевірити хеш
echo "e3b0c44298fc1c... file.txt" | sha256sum -c
# file.txt: OK
# Різні алгоритми
md5sum file.txt # НЕ для безпеки!
sha1sum file.txt # Застарілий
sha384sum file.txt
sha512sum file.txt
# OpenSSL
openssl dgst -sha256 file.txt
HMAC (Hash-based Message Authentication Code)¶
HMAC = хеш + секретний ключ = верифікація цілісності та автентичності.
┌─────────────────────────────────────────────────────────────────┐
│ Простий хеш: будь-хто може обчислити │
│ │
│ HMAC: тільки хто знає ключ може обчислити та перевірити │
│ │
│ HMAC(key, message) = hash(key || hash(key || message)) │
│ │
│ Використання: │
│ • API автентифікація │
│ • JWT підпис │
│ • Cookie захист │
└─────────────────────────────────────────────────────────────────┘
# Обчислити HMAC
echo -n "message" | openssl dgst -sha256 -hmac "secretkey"
# SHA256(stdin)= 5c9a4c9fa5f21d3e0a9e8c9f4c3d5b1e...
# В Python
import hmac, hashlib
hmac.new(b"secretkey", b"message", hashlib.sha256).hexdigest()
Цифровий підпис¶
Як працює¶
flowchart LR
subgraph signing["Підписання"]
DOC1["📄 Document"] --> HASH1["SHA-256"]
HASH1 --> H1["Hash"]
H1 --> ENC["Encrypt"]
PRIV["🔑 Private Key"] --> ENC
ENC --> SIG["✍️ Signature"]
end
style PRIV fill:#fee2e2
style SIG fill:#d1fae5flowchart LR
subgraph verify["Верифікація"]
SIG2["✍️ Signature"] --> DEC["Decrypt"]
PUB["🔓 Public Key"] --> DEC
DEC --> H1["Hash1"]
DOC2["📄 Document"] --> HASH2["SHA-256"]
HASH2 --> H2["Hash2"]
H1 --> CMP{{"Hash1 = Hash2?"}}
H2 --> CMP
CMP -->|Так| VALID["✅ Valid"]
CMP -->|Ні| INVALID["❌ Invalid"]
end
style PUB fill:#d1fae5
style VALID fill:#d1fae5
style INVALID fill:#fee2e2Приклад з OpenSSL¶
# Генерувати ключі
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -pubout -out public.pem
# Підписати файл
openssl dgst -sha256 -sign private.pem -out signature.bin document.txt
# Верифікувати підпис
openssl dgst -sha256 -verify public.pem -signature signature.bin document.txt
# Verified OK
GPG підпис¶
# Підписати файл
gpg --sign document.txt # Бінарний підпис
gpg --clearsign document.txt # Текстовий підпис
gpg --detach-sign document.txt # Окремий файл підпису
# Верифікувати
gpg --verify document.txt.sig document.txt
Key Derivation Functions (KDF)¶
Навіщо потрібні?¶
Паролі зазвичай слабкі. KDF роблять їх сильнішими.
┌─────────────────────────────────────────────────────────────────┐
│ Проблема: │
│ Пароль "password123" → легко зламати brute-force │
│ │
│ Рішення: │
│ KDF(password, salt, iterations) → криптографічний ключ │
│ │
│ • Salt — унікальне випадкове значення (запобігає rainbow tables)
│ • Iterations — кількість повторень (уповільнює brute-force) │
│ • Memory — використання RAM (ускладнює GPU атаки) │
└─────────────────────────────────────────────────────────────────┘
Алгоритми¶
| Алгоритм | Тип | Використання |
|---|---|---|
| PBKDF2 | Ітеративний | Legacy, LUKS1 |
| bcrypt | Memory-hard | Паролі (старий стандарт) |
| scrypt | Memory-hard | Паролі, криптовалюти |
| Argon2 | Memory-hard | Рекомендовано |
Argon2 — сучасний стандарт¶
# argon2 приклад (якщо встановлений)
echo -n "password" | argon2 somesalt -t 3 -m 12 -p 1
# В Python
from argon2 import PasswordHasher
ph = PasswordHasher()
hash = ph.hash("password")
# $argon2id$v=19$m=65536,t=3,p=4$...
# Верифікація
ph.verify(hash, "password") # True
Генерація випадкових чисел¶
CSPRNG (Cryptographically Secure PRNG)¶
┌─────────────────────────────────────────────────────────────────┐
│ Звичайний PRNG (rand(), Math.random()): │
│ • Передбачуваний (якщо знати seed) │
│ • НЕ для криптографії! │
│ │
│ CSPRNG (/dev/urandom, CryptoRandom): │
│ • Непередбачуваний │
│ • Використовує ентропію системи │
│ • Безпечний для криптографії │
└─────────────────────────────────────────────────────────────────┘
Linux¶
# Читати випадкові байти
head -c 32 /dev/urandom | xxd
# Генерувати випадкову строку
openssl rand -hex 32
# або
openssl rand -base64 32
# Генерувати пароль
< /dev/urandom tr -dc 'A-Za-z0-9!@#$%' | head -c 20
Python¶
# Правильно
import secrets
secrets.token_hex(32) # Випадковий hex
secrets.token_urlsafe(32) # URL-safe base64
secrets.randbelow(100) # Випадкове число 0-99
# НЕПРАВИЛЬНО для криптографії!
import random
random.randint(0, 100) # Передбачуваний!
Практичні рекомендації¶
Що використовувати¶
┌─────────────────────────────────────────────────────────────────┐
│ Задача │ Рекомендація │
├──────────────────────────────┼─────────────────────────────────┤
│ Симетричне шифрування │ AES-256-GCM │
│ Асиметричне шифрування │ RSA-4096 або X25519 │
│ Цифровий підпис │ Ed25519 або RSA-4096 │
│ Хешування │ SHA-256 або SHA-3 │
│ Хешування паролів │ Argon2id │
│ HMAC │ HMAC-SHA256 │
│ Key exchange │ X25519 або ECDH │
│ TLS │ TLS 1.3 │
└──────────────────────────────┴─────────────────────────────────┘
Чого уникати¶
┌─────────────────────────────────────────────────────────────────┐
│ НІКОЛИ не використовувати: │
│ │
│ • MD5, SHA-1 для безпеки │
│ • DES, 3DES │
│ • ECB mode │
│ • RC4 │
│ • Власні криптографічні алгоритми │
│ • Hardcoded keys у коді │
│ • rand() для криптографії │
│ • Паролі без salt │
│ • RSA < 2048 біт │
└─────────────────────────────────────────────────────────────────┘
Підсумок¶
| Тип | Алгоритм | Використання |
|---|---|---|
| Симетричне | AES-256-GCM | Шифрування даних |
| Асиметричне | RSA, Ed25519 | TLS, підписи |
| Хеш | SHA-256 | Цілісність |
| KDF | Argon2 | Паролі |
| HMAC | HMAC-SHA256 | Автентифікація |
Головне правило: Використовуйте перевірені бібліотеки, не винаходьте власну криптографію!
Пов'язані теми¶
Шлях: security/cryptography-basics.md