> Какие требования по шифрованию данных существуют (Go)
Уровень: senior · Роль: backend · Язык: Go · Категория: Технические вопросы
Компании: Wildberries
Стек: Go
> Пример ответа
Короткий ответ
Требования к шифрованию данных делятся на три категории: шифрование в состоянии покоя (at rest), при передаче (in transit) и в процессе использования (in use). Для backend на Go это означает использование TLS 1.2+ для сетевого трафика, AES-256 или ChaCha20-Poly1305 для хранения, и управление ключами через KMS или Vault. Также важны требования регуляторов: PCI DSS, GDPR, 152-ФЗ - они задают минимальные алгоритмы, длину ключей и процедуры ротации.
Подробное объяснение
Шифрование данных - это не единое действие, а комплекс мер, распределённых по жизненному циклу данных. Основные требования:
Для данных at rest (базы, S3, диски):
- Алгоритмы: AES-256-GCM (предпочтительно), ChaCha20-Poly1305 для high-performance сценариев
- Ключи: минимум 256 бит, отдельные ключи для разных типов данных (tenant isolation)
- Обязательна ротация ключей - периодическая или по событию (компрометация, увольнение сотрудника)
- Шифрование на уровне приложения, а не только на уровне диска - иначе данные доступны администраторам БД
Для данных in transit:
- TLS 1.2 минимум, TLS 1.3 рекомендуется
- Отключение слабых cipher suites (RC4, 3DES, CBC-mode)
- HSTS для web-сервисов
- mTLS для service-to-service communication внутри кластера
Для данных in use (в оперативной памяти):
- Полное гомоморфное шифрование - пока не практично
- На практике: минимизация времени нахождения plaintext в памяти, zeroization после использования
- Secure enclaves (SGX, Nitro Enclaves) для особо чувствительных данных
Регуляторные требования:
- PCI DSS: требует шифрование PAN-данных, ключи минимум 128 бит, ротация не реже 1 раза в год
- GDPR: шифрование как техническая мера защиты, но не обязательное - важно доказать "appropriate safeguards"
- 152-ФЗ (РФ): для персональных данных - ГОСТ-алгоритмы (ГОСТ 28147-89, ГОСТ Р 34.12-2015) обязательны для госсектора
Управление ключами - самая частая точка отказа:
- Ключи не должны храниться в коде, env-переменных или рядом с данными
- Использование KMS (AWS KMS, GCP KMS) или self-hosted Vault
- Разделение ключей шифрования (DEK) и ключей, шифрующих ключи (KEK) - envelope encryption
На практике
Для Go-сервиса типичный набор требований:
- TLS-конфигурация - явно задавать
MinVersion: tls.VersionTLS12,CipherSuitesбез CBC и RC4,PreferServerCipherSuites: true - Шифрование секретов - использовать
ageилиsopsдля конфигов, Vault для runtime-секретов - Шифрование полей в БД - не шифровать всю колонку, а использовать deterministic encryption (AES-SIV) для полей, по которым нужен поиск, и random encryption для остальных
- Envelope encryption - генерировать DEK для каждого объекта, шифровать DEK мастер-ключом из KMS
- Ротация - автоматизировать через CI/CD, хранить историю версий ключей для дешифровки старых данных
- Логирование - не логировать ключи, токены, plaintext; маскировать чувствительные поля
Важный нюанс: шифрование не заменяет access control. Если злоумышленник получил доступ к приложению - он получит и расшифрованные данные. Поэтому шифрование - это defence in depth, а не единственная мера.
Пример кода
GO// Пример envelope encryption с AWS KMSimport ("context""crypto/aes""crypto/cipher""crypto/rand""encoding/base64""fmt""github.com/aws/aws-sdk-go-v2/service/kms")type Encryptor struct {kmsClient *kms.ClientkeyID string}func (e *Encryptor) Encrypt(ctx context.Context, plaintext []byte) ([]byte, error) {// 1. Генерируем DEK (data encryption key)dek := make([]byte, 32)if _, err := rand.Read(dek); err != nil {return nil, fmt.Errorf("generate dek: %w", err)}// 2. Шифруем данные AES-256-GCMblock, err := aes.NewCipher(dek)if err != nil {return nil, err}gcm, err := cipher.NewGCM(block)if err != nil {return nil, err}nonce := make([]byte, gcm.NonceSize())if _, err := rand.Read(nonce); err != nil {return nil, err}ciphertext := gcm.Seal(nonce, nonce, plaintext, nil)// 3. Шифруем DEK мастер-ключом через KMSencDek, err := e.kmsClient.Encrypt(ctx, &kms.EncryptInput{KeyId: &e.keyID,Plaintext: dek,})if err != nil {return nil, fmt.Errorf("kms encrypt: %w", err)}// 4. Упаковываем: версия + зашифрованный DEK + ciphertextresult := make([]byte, 0, 1+len(encDek.CiphertextBlob)+len(ciphertext))result = append(result, 0x01) // versionresult = append(result, encDek.CiphertextBlob...)result = append(result, ciphertext...)return []byte(base64.StdEncoding.EncodeToString(result)), nil}func (e *Encryptor) Decrypt(ctx context.Context, data []byte) ([]byte, error) {raw, err := base64.StdEncoding.DecodeString(string(data))if err != nil {return nil, err}if len(raw) < 1 || raw[0] != 0x01 {return nil, fmt.Errorf("unsupported version")}// Формат: version(1) + encDekLen(4) + encDek + nonce+ciphertextencDekLen := int(raw[1])<<24 | int(raw[2])<<16 | int(raw[3])<<8 | int(raw[4])encDek := raw[5 : 5+encDekLen]payload := raw[5+encDekLen:]// Расшифровываем DEKdekResp, err := e.kmsClient.Decrypt(ctx, &kms.DecryptInput{CiphertextBlob: encDek,KeyId: &e.keyID,})if err != nil {return nil, fmt.Errorf("kms decrypt: %w", err)}// Расшифровываем данныеblock, err := aes.NewCipher(dekResp.Plaintext)if err != nil {return nil, err}gcm, err := cipher.NewGCM(block)if err != nil {return nil, err}nonceSize := gcm.NonceSize()if len(payload) < nonceSize {return nil, fmt.Errorf("payload too short")}return gcm.Open(nil, payload[:nonceSize], payload[nonceSize:], nil)}
Как отвечать на собеседовании
Начните с классификации: at rest, in transit, in use. Затем переходите к конкретике для Go: TLS-конфигурация в net/http, использование crypto/aes и crypto/cipher, интеграция с KMS. Обязательно упомяните управление ключами - это показывает понимание полного цикла, а не только алгоритмов.
Если спрашивают про регуляторику - не углубляйтесь в юридические детали, а скажите, какие технические требования вытекают из стандартов: минимальная длина ключа, алгоритмы, процедуры ротации. Для РФ добавьте про ГОСТ - это важно для госсектора и банков.
Хорошо показать trade-off: например, deterministic encryption (AES-SIV) позволяет искать по зашифрованным полям, но снижает безопасность - это демонстрирует инженерное мышление.
Что проверяет интервьюер
- Понимание разницы между шифрованием at rest и in transit - это база, но многие путают
- Знание конкретных алгоритмов и параметров: почему AES-GCM, а не AES-CBC; почему TLS 1.2 минимум
- Понимание envelope encryption - это отличает senior от middle
- Осознание, что шифрование - не панацея: access control, key management, rotation не менее важны
- Практический опыт: как хранить ключи, как делать ротацию без даунтайма, как дешифровать старые данные после смены ключа
Типичные ошибки
- Ответ только про TLS - забывают про at rest и in use
- Предложение шифровать всё подряд одним ключом - нет разделения DEK/KEK, нет ротации
- Утверждение, что шифрование в БД решает все проблемы безопасности - игнорируют access control
- Незнание разницы между symmetric и asymmetric шифрованием в контексте TLS
- Предложение использовать самописные криптоалгоритмы - это красный флаг
- Забывают про производительность: шифрование каждой колонки в БД может убить latency, нужен баланс
- Не упоминают zeroization и защиту памяти для ключей в Go -
runtime.KeepAlive,memclr
> Похожие задачи по Go
Какие данные кэшируются и как работает кэширование
Как подбирать тайм-ауты для backend взаимодействия, например HTTP запросов
Какая связь между таблицами людей и адресов в базе данных
Кто пишет миграции в проекте
> Похожие задачи по backend
Какие данные кэшируются и как работает кэширование
Как подбирать тайм-ауты для backend взаимодействия, например HTTP запросов
Какая связь между таблицами людей и адресов в базе данных
Кто пишет миграции в проекте
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью