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

Що таке криптографія?

Криптографія — це наука про захист інформації за допомогою математичних алгоритмів. Вона забезпечує:

  • Конфіденційність — тільки авторизовані особи можуть прочитати дані
  • Цілісність — дані не були змінені
  • Автентичність — підтвердження особи відправника
  • Неспростовність — відправник не може заперечити відправлення
┌─────────────────────────────────────────────────────────────────┐
  Plaintext ────▶ [Encrypt] ────▶ Ciphertext ────▶ [Decrypt] ──▶│
  "Hello"                         "x7Gh2k"                    
                                                               
                   Key                               Key         
                                                                 
  Тільки хто має правильний ключ може розшифрувати              
└─────────────────────────────────────────────────────────────────┘

Симетричне шифрування

Принцип роботи

Один ключ для шифрування та дешифрування.

┌─────────────────────────────────────────────────────────────────┐
│  Alice                                              Bob         │
│                                                                 │
│  Plaintext: "Secret"                                           │
│       │                                                         │
│       ▼ Encrypt(key="password123")                             │
│  Ciphertext: "x7Gh2kL9..."                                     │
│       │                                                         │
│       │ ═══════════ передача ═══════════▶                      │
│       │                                     │                   │
│       │                                     ▼                   │
│       │                        Decrypt(key="password123")       │
│       │                                     │                   │
│       │                                     ▼                   │
│       │                        Plaintext: "Secret"              │
│                                                                 │
│  Проблема: Як безпечно передати ключ?                          │
└─────────────────────────────────────────────────────────────────┘

Алгоритми

Алгоритм Розмір ключа Статус Примітки
DES 56 біт Небезпечний Не використовувати!
3DES 168 біт Застарілий Повільний
AES-128 128 біт Безпечний Стандарт
AES-256 256 біт Дуже безпечний Рекомендовано
ChaCha20 256 біт Безпечний Швидкий на CPU без AES-NI

Режими шифрування (Block Cipher Modes)

┌─────────────────────────────────────────────────────────────────┐
  ECB (Electronic Codebook)  НЕ ВИКОРИСТОВУВАТИ!               
                                                                 
  Однакові блоки  однаковий шифротекст                         
  [Block1]  [EncB1]                                            
  [Block1]  [EncB1]   той самий!                              
  [Block2]  [EncB2]                                            
                                                                 
  Видно паттерни в даних!                                       
├─────────────────────────────────────────────────────────────────┤
  CBC (Cipher Block Chaining)  краще                           
                                                                 
  IV ─────────▶ XOR ─▶ [Encrypt] ─▶ Ciphertext1 ──┐             
  [Block1] ────┘                                                
                                                                
  [Block2] ─────────▶ XOR ─▶ [Encrypt] ─▶ Ciphertext2           
                                                                 
  Потребує IV (Initialization Vector), послідовне               
├─────────────────────────────────────────────────────────────────┤
  GCM (Galois/Counter Mode)  РЕКОМЕНДОВАНО                     
                                                                 
   Authenticated encryption (шифрування + цілісність)          
   Паралельне шифрування (швидко)                              
   Включає authentication tag                                   
                                                                 
  AES-256-GCM  gold standard                                   
└─────────────────────────────────────────────────────────────────┘

Приклад з 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).

┌─────────────────────────────────────────────────────────────────┐
  Key Pair Generation:                                          
                                                                 
  [Generate] ──▶ Public Key (можна поширювати)                  
              └▶ Private Key (ЗБЕРІГАТИ В СЕКРЕТІ!)             
                                                                 
├─────────────────────────────────────────────────────────────────┤
  Шифрування:                                                    
                                                                 
  Alice хоче надіслати повідомлення Bob:                        
                                                                 
  1. Bob публікує свій Public Key                               
  2. Alice шифрує: Encrypt(message, Bob's Public Key)           
  3. Тільки Bob може розшифрувати своїм Private Key             
                                                                 
  "Публічний ключ — замок, приватний — ключ від замка"          
└─────────────────────────────────────────────────────────────────┘

Алгоритми

Алгоритм Тип Розмір ключа Використання
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()

Цифровий підпис

Як працює

┌─────────────────────────────────────────────────────────────────┐
  Підписання (Signing):                                          
                                                                 
  1. Обчислити хеш документа                                    
  2. Зашифрувати хеш ПРИВАТНИМ ключем = підпис                  
                                                                 
  Document ──▶ [Hash] ──▶ [Encrypt with Private Key] ──▶ Signature
                                                                 
├─────────────────────────────────────────────────────────────────┤
  Верифікація (Verifying):                                       
                                                                 
  1. Розшифрувати підпис ПУБЛІЧНИМ ключем = хеш                 
  2. Обчислити хеш документа                                    
  3. Порівняти хеші                                              
                                                                 
  Signature ──▶ [Decrypt with Public Key] ──▶ Hash1             
  Document ──▶ [Hash] ──▶ Hash2                                 
  Hash1 == Hash2 ?  Valid :  Invalid                          
└─────────────────────────────────────────────────────────────────┘

Приклад з 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 — захист серверів

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

UMTC Wiki © 2026 | Ukrainian Military Tactical Communications