Ответ
Симметричное шифрование — это метод криптографии, при котором один и тот же ключ используется как для шифрования (превращения открытого текста в шифротекст), так и для расшифровки (обратного процесса).
Представьте, что у вас есть сейф с одним ключом. Вы запираете им ценности, а чтобы их достать, получатель должен использовать точную копию того же ключа.
Ключевые характеристики:
- (+) Высокая скорость: Симметричные алгоритмы (например, AES) значительно быстрее асимметричных (например, RSA), что делает их идеальными для шифрования больших объемов данных.
- (-) Проблема распределения ключей: Главный недостаток — необходимость безопасно передать секретный ключ получателю. Если ключ перехватят, вся система будет скомпрометирована.
- Популярные алгоритмы: AES (Advanced Encryption Standard), ChaCha20, DES, 3DES, Blowfish.
Пример на Go (AES в режиме GCM):
AES-GCM — это современный и рекомендуемый режим, так как он обеспечивает не только конфиденциальность, но и аутентифицированное шифрование (AEAD), то есть защищает от подделки зашифрованных данных.
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"fmt"
"io"
)
// encrypt шифрует данные с использованием AES-GCM
func encrypt(plaintext []byte, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
// Nonce (number used once) — это уникальный для каждого шифрования номер.
// Он не секретный, но должен быть уникальным для данной пары ключ-сообщение.
nonce := make([]byte, gcm.NonceSize())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, err
}
// Шифруем и добавляем nonce в начало шифротекста для последующей расшифровки.
ciphertext := gcm.Seal(nonce, nonce, plaintext, nil)
return ciphertext, nil
}
// decrypt расшифровывает данные
func decrypt(ciphertext []byte, key []byte) ([]byte, error) {
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
gcm, err := cipher.NewGCM(block)
if err != nil {
return nil, err
}
nonceSize := gcm.NonceSize()
if len(ciphertext) < nonceSize {
return nil, fmt.Errorf("ciphertext too short")
}
nonce, encryptedMessage := ciphertext[:nonceSize], ciphertext[nonceSize:]
return gcm.Open(nil, nonce, encryptedMessage, nil)
}
func main() {
// Ключ должен быть 16, 24 или 32 байта для AES-128, AES-192, AES-256.
key := make([]byte, 32)
// В реальном приложении ключ должен быть сгенерирован и сохранен безопасно.
rand.Read(key)
data := []byte("очень секретное сообщение")
encrypted, _ := encrypt(data, key)
decrypted, _ := decrypt(encrypted, key)
fmt.Printf("Расшифровано: %sn", string(decrypted))
}
Практическое применение:
- HTTPS/TLS: После того как клиент и сервер безопасно обменялись сессионным ключом с помощью асимметричного шифрования, весь последующий трафик шифруется симметрично с помощью этого ключа.
- Шифрование файлов и дисков: (например, BitLocker, VeraCrypt).
- Защита данных в базах данных.