Good

Основи криптографії

Криптографія — це наука про захист інформації за допомогою математичних алгоритмів. Без криптографії неможливий безпечний інтернет: банкінг, HTTPS, SSH, VPN — все базується на цих принципах.

💡 Чому це важливо для UMTC?
Вся комунікація UMTC захищена криптографією: Matrix E2E encryption, WireGuard VPN, SSH доступ до серверів. Розуміння основ допомагає правильно налаштовувати та діагностувати.

Що забезпечує криптографія?

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:#fee2e2
flowchart 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:#fee2e2
sequenceDiagram
    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:#d1fae5
flowchart 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 Автентифікація

Головне правило: Використовуйте перевірені бібліотеки, не винаходьте власну криптографію!


Пов'язані теми

  • TLS/SSL — шифрування з'єднань
  • SSH ключі — практичне використання
  • Hardening — захист серверів
  • Matrix — E2E шифрування в месенджері
  • WireGuard — сучасний VPN з криптографією

Шлях: security/cryptography-basics.md

UMTC Wiki © 2026 | Ukrainian Military Tactical Communications