> Какие требования по шифрованию данных существуют (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-сервиса типичный набор требований:

  1. TLS-конфигурация - явно задавать MinVersion: tls.VersionTLS12, CipherSuites без CBC и RC4, PreferServerCipherSuites: true
  2. Шифрование секретов - использовать age или sops для конфигов, Vault для runtime-секретов
  3. Шифрование полей в БД - не шифровать всю колонку, а использовать deterministic encryption (AES-SIV) для полей, по которым нужен поиск, и random encryption для остальных
  4. Envelope encryption - генерировать DEK для каждого объекта, шифровать DEK мастер-ключом из KMS
  5. Ротация - автоматизировать через CI/CD, хранить историю версий ключей для дешифровки старых данных
  6. Логирование - не логировать ключи, токены, plaintext; маскировать чувствительные поля

Важный нюанс: шифрование не заменяет access control. Если злоумышленник получил доступ к приложению - он получит и расшифрованные данные. Поэтому шифрование - это defence in depth, а не единственная мера.

Пример кода

GO
// Пример envelope encryption с AWS KMS
import (
"context"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"fmt"
"github.com/aws/aws-sdk-go-v2/service/kms"
)
type Encryptor struct {
kmsClient *kms.Client
keyID 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-GCM
block, 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 мастер-ключом через KMS
encDek, 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 + ciphertext
result := make([]byte, 0, 1+len(encDek.CiphertextBlob)+len(ciphertext))
result = append(result, 0x01) // version
result = 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+ciphertext
encDekLen := int(raw[1])<<24 | int(raw[2])<<16 | int(raw[3])<<8 | int(raw[4])
encDek := raw[5 : 5+encDekLen]
payload := raw[5+encDekLen:]
// Расшифровываем DEK
dekResp, 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

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью