keywrap

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 13, 2026 License: AGPL-3.0 Imports: 6 Imported by: 0

Documentation

Overview

Package keywrap — обёртка приватной половины подписного ключа для хранения в базе.

Чей это ключ

Ключ обёртки — уже объявленная ручка `authn.jwks-encryption-key-hex` (приёмка §2.5). Второй ручки об этом предмете не заводится: одна из двух неизбежно оказалась бы необязательной, и профиль развёртывания, задавший «не ту», выглядел бы настроенным.

Почему AES-256-GCM

Форма ручки уже объявлена ровно 32 байтами, то есть размером ключа симметричного шифра. Изобретать второй размер незачем. GCM выбран потому, что даёт подлинность вместе с сокрытием: подменённая в базе строка не разворачивается, а не разворачивается в мусор, который потом окажется «ключом».

Ключей может быть НЕСКОЛЬКО, и это единственный путь смены

Ключ обёртки — секрет, а у секрета обязан быть путь смены: утёк, скомпрометирован носитель, сменился владелец, истёк срок политики. Одно значение такого пути не даёт вовсе: новое значение не открывает ни одной уже записанной приватной половины, и вернуть их нечем.

Поэтому обёртка принимает ПЕРЕЧЕНЬ: ПЕРВЫЙ ключ оборачивает, ВСЕ открывают (задача #1065). Смена — это постановка нового ключа первым при сохранённом прежнем: записанного никто не трогает, простоя нет, а хранилище переходит на новый ключ само, по мере того как ключница порождает ключи и снимает старые.

Чего перечень НЕ даёт: ВЫВОДА ключа. Прежний ключ открывает написанное им до тех пор, пока в наборе есть хоть одна строка, обёрнутая им, — и утёкший ключ снимается из перечня не раньше. Переобёртывание уже записанного — отдельная работа со своим окном и своим решением о срыве на середине.

Что этот пакет НЕ делает

Он не журналирует, не оборачивает ошибки текстом, содержащим материал, и не печатает ни одного байта ни на каком пути (§6.10). Текст отказа называет операцию, а не значение.

Index

Constants

View Source
const KeySize = 32

KeySize — размер ключа обёртки в байтах. Объявлен ЧИСЛОМ ровно здесь; страж старта конфигурации сверяется с этим числом, а не со своей копией.

Variables

View Source
var ErrNotWrapped = errors.New("keywrap: value is not a wrapped key")

ErrNotWrapped — предъявленное значение обёрткой не является (слишком коротко, чтобы нести хотя бы вектор инициализации).

View Source
var ErrUnwrap = errors.New("keywrap: unwrap failed")

ErrUnwrap — обёртка не снимается: ключ не тот, значение повреждено или подменено. Причина НЕ различается намеренно — различение подсказывало бы предъявителю, какая половина неверна.

Functions

This section is empty.

Types

type Wrapper

type Wrapper struct {
	// contains filtered or unexported fields
}

Wrapper оборачивает и разворачивает приватный материал.

Ключей может быть несколько: первый делает КАЖДУЮ новую обёртку, все годятся для снятия. Разделение полей выражает это по построению — «обернуть чем-то из перечня» здесь не выражается, а не запрещено правилом.

func New

func New(keys ...[]byte) (*Wrapper, error)

New строит обёртку на ПЕРЕЧНЕ ключей объявленного размера: первый оборачивает, все открывают.

Перечень из одного ключа — законный и самый частый случай; профиль развёртывания, назвавший одно значение, не меняется оттого, что смена ключа стала возможной.

Пустой перечень — ОТКАЗ. Обёртка без ключей не открыла бы ничего, а построенная выглядела бы собранной: «не сужаем» здесь читалось бы как «запрещаем».

Ключ негодного размера — ОТКАЗ на ЛЮБОЙ позиции, а не усечение и не растяжение: «привели к нужной длине» означает, что ошибка настройки становится рабочим режимом. Отказ называет ПОЗИЦИЮ — со списком из трёх значений оператор иначе не знает, какое чинить, — и никогда значение.

func (*Wrapper) KeyCount

func (w *Wrapper) KeyCount() int

KeyCount — сколько ключей названо.

Печатается при старте: перечень растёт с каждой сменой и не убывает сам, а «названо шесть ключей» иначе невидимо ниоткуда — то есть работу по выводу прежних ключей некому начать.

func (*Wrapper) Unwrap

func (w *Wrapper) Unwrap(wrapped []byte) ([]byte, error)

Unwrap снимает обёртку ЛЮБЫМ из названных ключей, в порядке объявления.

Перебор не ослабляет проверку подлинности: каждый ключ проверяет метку целостности сам, поэтому подменённое значение не открывается НИ ОДНИМ — и перечень из десяти отвергает ровно то же, что перечень из одного.

Порядок выбран не для красоты: первым стоит текущий ключ, а самый частый читатель — подписывающий ключ, только что записанный им же. Перебор поэтому оканчивается на первом ключе на горячем пути, а длина перечня оплачивается лишь на строках, доставшихся от прежних ключей.

Текст отказа не несёт ни байта материала и не называет, чем именно значение негодно и какой ключ его не открыл: у сообщения об ошибке нет адресата, которому эта разница помогала бы законно.

func (*Wrapper) Wrap

func (w *Wrapper) Wrap(plain []byte) ([]byte, error)

Wrap оборачивает приватный материал. Вектор инициализации свой у каждого вызова и хранится префиксом — двух одинаковых обёрток одного ключа не бывает.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL