[#529] Use salt when deriving the encryption key #572
7 changed files with 108 additions and 108 deletions
|
@ -19,6 +19,11 @@ import (
|
|||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
const (
|
||||
secretLength = 32
|
||||
saltLength = 16
|
||||
)
|
||||
|
||||
// Box represents friendly AccessBox.
|
||||
type Box struct {
|
||||
Gate *GateData
|
||||
|
@ -109,7 +114,7 @@ func PackTokens(gatesData []*GateData, secret []byte, isCustomSecret bool) (*Acc
|
|||
box.IsCustom = isCustomSecret
|
||||
|
||||
if secret == nil {
|
||||
secret, err = generateSecret()
|
||||
secret, err = generateRandomBytes(secretLength)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("failed to generate accessKey as hex: %w", err)
|
||||
}
|
||||
|
@ -212,7 +217,12 @@ func encodeGate(ephemeralKey *keys.PrivateKey, seedKey *keys.PublicKey, tokens *
|
|||
return nil, fmt.Errorf("encode tokens: %w", err)
|
||||
}
|
||||
|
||||
encrypted, err := encrypt(ephemeralKey, seedKey, data)
|
||||
salt, err := generateRandomBytes(saltLength)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to generate salt for encryption key: %w", err)
|
||||
}
|
||||
|
||||
encrypted, err := encrypt(ephemeralKey, seedKey, data, salt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ecrypt tokens: %w", err)
|
||||
}
|
||||
|
@ -220,11 +230,12 @@ func encodeGate(ephemeralKey *keys.PrivateKey, seedKey *keys.PublicKey, tokens *
|
|||
gate := new(AccessBox_Gate)
|
||||
gate.GatePublicKey = seedKey.Bytes()
|
||||
gate.Tokens = encrypted
|
||||
gate.EncryptionKeySalt = salt
|
||||
return gate, nil
|
||||
}
|
||||
|
||||
func (x *AccessBox) decodeGate(gate *AccessBox_Gate, owner *keys.PrivateKey, seedKey *keys.PublicKey) (*GateData, error) {
|
||||
data, err := decrypt(owner, seedKey, gate.Tokens)
|
||||
data, err := decrypt(owner, seedKey, gate.Tokens, gate.EncryptionKeySalt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decrypt tokens: %w", err)
|
||||
}
|
||||
|
@ -273,16 +284,16 @@ func generateShared256(prv *keys.PrivateKey, pub *keys.PublicKey) (sk []byte, er
|
|||
return sk, nil
|
||||
}
|
||||
|
||||
func deriveKey(secret []byte) ([]byte, error) {
|
||||
func deriveKey(secret, salt []byte) ([]byte, error) {
|
||||
hash := sha256.New
|
||||
kdf := hkdf.New(hash, secret, nil, nil)
|
||||
kdf := hkdf.New(hash, secret, salt, nil)
|
||||
key := make([]byte, 32)
|
||||
_, err := io.ReadFull(kdf, key)
|
||||
return key, err
|
||||
}
|
||||
|
||||
func encrypt(owner *keys.PrivateKey, seedKey *keys.PublicKey, data []byte) ([]byte, error) {
|
||||
enc, err := getCipher(owner, seedKey)
|
||||
func encrypt(owner *keys.PrivateKey, seedKey *keys.PublicKey, data, salt []byte) ([]byte, error) {
|
||||
enc, err := getCipher(owner, seedKey, salt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get chiper: %w", err)
|
||||
}
|
||||
|
@ -295,8 +306,8 @@ func encrypt(owner *keys.PrivateKey, seedKey *keys.PublicKey, data []byte) ([]by
|
|||
return enc.Seal(nonce, nonce, data, nil), nil
|
||||
}
|
||||
|
||||
func decrypt(owner *keys.PrivateKey, seedKey *keys.PublicKey, data []byte) ([]byte, error) {
|
||||
dec, err := getCipher(owner, seedKey)
|
||||
func decrypt(owner *keys.PrivateKey, seedKey *keys.PublicKey, data, salt []byte) ([]byte, error) {
|
||||
dec, err := getCipher(owner, seedKey, salt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("get chiper: %w", err)
|
||||
}
|
||||
|
@ -309,13 +320,13 @@ func decrypt(owner *keys.PrivateKey, seedKey *keys.PublicKey, data []byte) ([]by
|
|||
return dec.Open(nil, nonce, cypher, nil)
|
||||
}
|
||||
|
||||
func getCipher(owner *keys.PrivateKey, seedKey *keys.PublicKey) (cipher.AEAD, error) {
|
||||
func getCipher(owner *keys.PrivateKey, seedKey *keys.PublicKey, salt []byte) (cipher.AEAD, error) {
|
||||
secret, err := generateShared256(owner, seedKey)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("generate shared key: %w", err)
|
||||
}
|
||||
|
||||
key, err := deriveKey(secret)
|
||||
key, err := deriveKey(secret, salt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("derive key: %w", err)
|
||||
}
|
||||
|
@ -323,8 +334,8 @@ func getCipher(owner *keys.PrivateKey, seedKey *keys.PublicKey) (cipher.AEAD, er
|
|||
return chacha20poly1305.NewX(key)
|
||||
}
|
||||
|
||||
func generateSecret() ([]byte, error) {
|
||||
b := make([]byte, 32)
|
||||
_, err := io.ReadFull(rand.Reader, b)
|
||||
func generateRandomBytes(length int) ([]byte, error) {
|
||||
b := make([]byte, length)
|
||||
_, err := rand.Read(b)
|
||||
return b, err
|
||||
}
|
||||
|
|
|
@ -159,8 +159,9 @@ type AccessBox_Gate struct {
|
|||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
Tokens []byte `protobuf:"bytes,1,opt,name=tokens,proto3" json:"tokens,omitempty"`
|
||||
GatePublicKey []byte `protobuf:"bytes,2,opt,name=gatePublicKey,proto3" json:"gatePublicKey,omitempty"`
|
||||
Tokens []byte `protobuf:"bytes,1,opt,name=tokens,proto3" json:"tokens,omitempty"`
|
||||
GatePublicKey []byte `protobuf:"bytes,2,opt,name=gatePublicKey,proto3" json:"gatePublicKey,omitempty"`
|
||||
EncryptionKeySalt []byte `protobuf:"bytes,3,opt,name=encryptionKeySalt,proto3" json:"encryptionKeySalt,omitempty"`
|
||||
}
|
||||
|
||||
func (x *AccessBox_Gate) Reset() {
|
||||
|
@ -209,6 +210,13 @@ func (x *AccessBox_Gate) GetGatePublicKey() []byte {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (x *AccessBox_Gate) GetEncryptionKeySalt() []byte {
|
||||
if x != nil {
|
||||
return x.EncryptionKeySalt
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type AccessBox_ContainerPolicy struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
|
@ -269,7 +277,7 @@ var File_creds_accessbox_accessbox_proto protoreflect.FileDescriptor
|
|||
var file_creds_accessbox_accessbox_proto_rawDesc = []byte{
|
||||
0x0a, 0x1f, 0x63, 0x72, 0x65, 0x64, 0x73, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f,
|
||||
0x78, 0x2f, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x2e, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x12, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x22, 0xe3, 0x02, 0x0a,
|
||||
0x6f, 0x12, 0x09, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x22, 0x91, 0x03, 0x0a,
|
||||
0x09, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x42, 0x6f, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65,
|
||||
0x65, 0x64, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x65, 0x65,
|
||||
0x64, 0x4b, 0x65, 0x79, 0x12, 0x2f, 0x0a, 0x05, 0x67, 0x61, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20,
|
||||
|
@ -282,29 +290,31 @@ var file_creds_accessbox_accessbox_proto_rawDesc = []byte{
|
|||
0x6c, 0x69, 0x63, 0x79, 0x52, 0x0f, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x50,
|
||||
0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x69, 0x73, 0x43, 0x75, 0x73, 0x74, 0x6f,
|
||||
0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x69, 0x73, 0x43, 0x75, 0x73, 0x74, 0x6f,
|
||||
0x6d, 0x1a, 0x44, 0x0a, 0x04, 0x47, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x6b,
|
||||
0x6d, 0x1a, 0x72, 0x0a, 0x04, 0x47, 0x61, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x6b,
|
||||
0x65, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x6f, 0x6b, 0x65, 0x6e,
|
||||
0x73, 0x12, 0x24, 0x0a, 0x0d, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b,
|
||||
0x65, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x67, 0x61, 0x74, 0x65, 0x50, 0x75,
|
||||
0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x1a, 0x59, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61,
|
||||
0x69, 0x6e, 0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2e, 0x0a, 0x12, 0x6c, 0x6f,
|
||||
0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74,
|
||||
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6f,
|
||||
0x6c, 0x69, 0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69,
|
||||
0x63, 0x79, 0x22, 0x6e, 0x0a, 0x06, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09,
|
||||
0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x09, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x65,
|
||||
0x61, 0x72, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52,
|
||||
0x0b, 0x62, 0x65, 0x61, 0x72, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x24, 0x0a, 0x0d,
|
||||
0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x03, 0x20,
|
||||
0x03, 0x28, 0x0c, 0x52, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65,
|
||||
0x6e, 0x73, 0x42, 0x46, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x2e, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66,
|
||||
0x73, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x54, 0x72, 0x75, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64,
|
||||
0x4c, 0x61, 0x62, 0x2f, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2d, 0x73, 0x33, 0x2d, 0x67,
|
||||
0x77, 0x2f, 0x63, 0x72, 0x65, 0x64, 0x73, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x62, 0x6f, 0x78,
|
||||
0x3b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
|
||||
0x6f, 0x33,
|
||||
0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2c, 0x0a, 0x11, 0x65, 0x6e, 0x63, 0x72, 0x79,
|
||||
0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x53, 0x61, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01,
|
||||
0x28, 0x0c, 0x52, 0x11, 0x65, 0x6e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65,
|
||||
0x79, 0x53, 0x61, 0x6c, 0x74, 0x1a, 0x59, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e,
|
||||
0x65, 0x72, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x12, 0x2e, 0x0a, 0x12, 0x6c, 0x6f, 0x63, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x12, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f,
|
||||
0x6e, 0x73, 0x74, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x6f, 0x6c, 0x69,
|
||||
0x63, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79,
|
||||
0x22, 0x6e, 0x0a, 0x06, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x65,
|
||||
0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73,
|
||||
0x65, 0x63, 0x72, 0x65, 0x74, 0x4b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x0b, 0x62, 0x65, 0x61, 0x72,
|
||||
0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62,
|
||||
0x65, 0x61, 0x72, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x24, 0x0a, 0x0d, 0x73, 0x65,
|
||||
0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28,
|
||||
0x0c, 0x52, 0x0d, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73,
|
||||
0x42, 0x46, 0x5a, 0x44, 0x67, 0x69, 0x74, 0x2e, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2e,
|
||||
0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x54, 0x72, 0x75, 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x4c, 0x61,
|
||||
0x62, 0x2f, 0x66, 0x72, 0x6f, 0x73, 0x74, 0x66, 0x73, 0x2d, 0x73, 0x33, 0x2d, 0x67, 0x77, 0x2f,
|
||||
0x63, 0x72, 0x65, 0x64, 0x73, 0x2f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x62, 0x6f, 0x78, 0x3b, 0x61,
|
||||
0x63, 0x63, 0x65, 0x73, 0x73, 0x62, 0x6f, 0x78, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
@ -10,6 +10,7 @@ message AccessBox {
|
|||
message Gate {
|
||||
bytes tokens = 1 [json_name = "tokens"];
|
||||
bytes gatePublicKey = 2 [json_name = "gatePublicKey"];
|
||||
bytes encryptionKeySalt = 3 [json_name = "encryptionKeySalt"];
|
||||
}
|
||||
|
||||
message ContainerPolicy {
|
||||
|
|
|
@ -23,6 +23,10 @@ func TestTokensEncryptDecrypt(t *testing.T) {
|
|||
tkn bearer.Token
|
||||
tkn2 bearer.Token
|
||||
)
|
||||
|
||||
salt, err := generateRandomBytes(saltLength)
|
||||
require.NoError(t, err)
|
||||
|
||||
sec, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
|
@ -32,16 +36,47 @@ func TestTokensEncryptDecrypt(t *testing.T) {
|
|||
tkn.SetEACLTable(*eacl.NewTable())
|
||||
require.NoError(t, tkn.Sign(sec.PrivateKey))
|
||||
|
||||
data, err := encrypt(cred, cred.PublicKey(), tkn.Marshal())
|
||||
require.NoError(t, err)
|
||||
t.Run("positive case without salt", func(t *testing.T) {
|
||||
data, err := encrypt(cred, cred.PublicKey(), tkn.Marshal(), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
rawTkn2, err := decrypt(cred, cred.PublicKey(), data)
|
||||
require.NoError(t, err)
|
||||
rawTkn2, err := decrypt(cred, cred.PublicKey(), data, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = tkn2.Unmarshal(rawTkn2)
|
||||
require.NoError(t, err)
|
||||
err = tkn2.Unmarshal(rawTkn2)
|
||||
require.NoError(t, err)
|
||||
|
||||
assertBearerToken(t, tkn, tkn2)
|
||||
assertBearerToken(t, tkn, tkn2)
|
||||
})
|
||||
|
||||
t.Run("positive case with salt", func(t *testing.T) {
|
||||
data, err := encrypt(cred, cred.PublicKey(), tkn.Marshal(), salt)
|
||||
require.NoError(t, err)
|
||||
|
||||
rawTkn2, err := decrypt(cred, cred.PublicKey(), data, salt)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = tkn2.Unmarshal(rawTkn2)
|
||||
require.NoError(t, err)
|
||||
|
||||
assertBearerToken(t, tkn, tkn2)
|
||||
})
|
||||
|
||||
t.Run("wrong salt", func(t *testing.T) {
|
||||
data, err := encrypt(cred, cred.PublicKey(), tkn.Marshal(), salt)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = decrypt(cred, cred.PublicKey(), data, nil)
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("wrong private key", func(t *testing.T) {
|
||||
data, err := encrypt(cred, cred.PublicKey(), tkn.Marshal(), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = decrypt(sec, cred.PublicKey(), data, nil)
|
||||
require.Error(t, err)
|
||||
})
|
||||
}
|
||||
|
||||
func TestBearerTokenInAccessBox(t *testing.T) {
|
||||
|
|
|
@ -199,6 +199,7 @@ It contains:
|
|||
in [spec](https://git.frostfs.info/TrueCloudLab/frostfs-api/src/commit/4c68d92468503b10282c8a92af83a56f170c8a3a/acl/types.proto#L189)
|
||||
* Marshaled session token - more detail
|
||||
in [spec](https://git.frostfs.info/TrueCloudLab/frostfs-api/src/commit/4c68d92468503b10282c8a92af83a56f170c8a3a/session/types.proto#L89)
|
||||
* Encryption Key Salt - randomly generated 16 bytes that are used to derivation the encryption key
|
||||
* Container placement policies:
|
||||
* `LocationsConstraint` - name of location constraint that can be used to create bucket/container using s3
|
||||
credentials related to this `AccessBox`
|
||||
|
@ -258,19 +259,20 @@ secp256r1 or prime256v1) is used (unless otherwise stated).
|
|||
* Create ephemeral key (`SeedKey`), it's need to generate shared secret
|
||||
* Generate random 32-byte (that after hex-encoded be `SecretAccessKey`) or use existing secret access key
|
||||
(if `AccessBox` is being updated rather than creating brand new) or use arbitrary user-provided string
|
||||
* Generate random 16-byte salt
|
||||
* Generate shared secret as [ECDH](https://en.wikipedia.org/wiki/Elliptic-curve_Diffie%E2%80%93Hellman)
|
||||
* Derive 32-byte key using shared secret from previous step with key derivation function based on
|
||||
* Derive 32-byte key using shared secret from previous step and the salt with key derivation function based on
|
||||
HMAC with SHA256 [HKDF](https://en.wikipedia.org/wiki/HKDF)
|
||||
* Encrypt marshaled [Tokens](../creds/accessbox) using derived key
|
||||
with [ChaCha20-Poly1305](https://en.wikipedia.org/wiki/ChaCha20-Poly1305) algorithm without additional data.
|
||||
|
||||
**Decryption:**
|
||||
|
||||
* Get public part of `SeedKey` from `AccessBox`
|
||||
* Get public part of `SeedKey` and the salt from `AccessBox`
|
||||
* Generate shared secret as follows:
|
||||
* Make scalar curve multiplication of public part of `SeedKey` and private part of s3-gw key
|
||||
* Use `X` part of multiplication (with zero padding at the beginning to fit 32-byte)
|
||||
* Derive 32-byte key using shared secret from previous step with key derivation function based on
|
||||
* Derive 32-byte key using shared secret from previous step and the salt with key derivation function based on
|
||||
HMAC with SHA256 [HKDF](https://en.wikipedia.org/wiki/HKDF)
|
||||
* Decrypt encrypted marshaled [Tokens](../creds/accessbox) using derived key
|
||||
with [ChaCha20-Poly1305](https://en.wikipedia.org/wiki/ChaCha20-Poly1305) algorithm without additional data.
|
||||
|
|
|
@ -10,6 +10,7 @@ package AccessBox {
|
|||
map Gate {
|
||||
GateKey => Encoded public gate key
|
||||
Encrypted tokens *--> Tokens
|
||||
EncryptionKeySalt => Salt for derivation the encryption key
|
||||
}
|
||||
|
||||
map ContainerPolicy {
|
||||
|
|
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 14 KiB |
Loading…
Reference in a new issue