package envelope import ( "context" "encoding/hex" "fmt" "os" "strings" ) // KeyFile is a Wrapper backed by a 32-byte AES-256 key loaded from a file. // The file should contain a 64-character hex-encoded key. // Intended for development and demo use; not suitable for production. type KeyFile struct { key []byte } var _ Wrapper = (*KeyFile)(nil) func LoadKeyFile(path string) (*KeyFile, error) { data, err := os.ReadFile(path) if err != nil { return nil, fmt.Errorf("reading key file: %w", err) } key, err := hex.DecodeString(strings.TrimSpace(string(data))) if err != nil { return nil, fmt.Errorf("decoding key: %w", err) } if len(key) != 32 { return nil, fmt.Errorf("key must be 32 bytes (64 hex chars), got %d", len(key)) } return &KeyFile{key: key}, nil } func (k *KeyFile) Wrap(ctx context.Context, dek []byte) ([]byte, error) { return aesGCMSeal(k.key, dek) } func (k *KeyFile) Unwrap(ctx context.Context, blob []byte) ([]byte, error) { return aesGCMOpen(k.key, blob) }