-
Notifications
You must be signed in to change notification settings - Fork 38
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use cosmosDB in the gateway and encrypt data with encryption key generated inside the enclave #2104
Merged
Merged
Changes from all commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
a6ca871
use cosmosDB as key value storage
zkokelj da5361b
change Storage interface, fix sqlite to be able to run locally, refac…
zkokelj e5c796c
remove not needed getPrivateKey
zkokelj e9edd47
remove getAccounts as it is no longer needed
zkokelj dde7135
tests passing with cosmosDB encrypted
zkokelj f0caa6d
refactored & added comments
zkokelj 0196b8a
use random key generated at startup
zkokelj b8437af
fix deployment script
zkokelj 1470467
remove migration files from the enclave files
zkokelj 18c034f
add certificates to the enclave to be able to check cosmosDB cert
zkokelj a2f97d3
run storage tests on sqlite by default
zkokelj e0a07c9
don't encode the data
zkokelj 421be90
remove ID field, because it is no neeed
zkokelj 9f8911a
wip
zkokelj 211b87c
wip
zkokelj a82f8d4
wip commit
zkokelj 23aa123
PR review fixes
zkokelj fda0871
storage with cache
zkokelj 611bc99
Merge branch 'main' into ziga/gateway_encrypted_kv_database
zkokelj File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,13 @@ | ||
package common | ||
|
||
type AccountDB struct { | ||
AccountAddress []byte | ||
Signature []byte | ||
SignatureType int | ||
type GWUserDB struct { | ||
UserId []byte `json:"userId"` | ||
PrivateKey []byte `json:"privateKey"` | ||
Accounts []GWAccountDB `json:"accounts"` | ||
} | ||
|
||
type UserDB struct { | ||
UserID []byte | ||
PrivateKey []byte | ||
type GWAccountDB struct { | ||
AccountAddress []byte `json:"accountAddress"` | ||
Signature []byte `json:"signature"` | ||
SignatureType int `json:"signatureType"` | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package encryption | ||
|
||
import ( | ||
"crypto/aes" | ||
"crypto/cipher" | ||
"crypto/hmac" | ||
"crypto/rand" | ||
"crypto/sha256" | ||
"errors" | ||
"fmt" | ||
"io" | ||
) | ||
|
||
// Encryptor provides AES-GCM encryption/decryption with the following characteristics: | ||
// - Uses AES-256-GCM (Galois/Counter Mode) with a 32-byte key | ||
// - Generates a random 12-byte nonce for each encryption operation using crypto/rand | ||
// - The nonce is prepended to the ciphertext output from Encrypt() and is generated | ||
// using crypto/rand.Reader for cryptographically secure random values | ||
// | ||
// Additionally provides HMAC-SHA256 hashing functionality: | ||
// - Uses the same 32-byte key as the encryption operations | ||
// - Generates a 32-byte (256-bit) message authentication code | ||
// - Suitable for creating secure message digests and verifying data integrity | ||
type Encryptor struct { | ||
gcm cipher.AEAD | ||
key []byte | ||
} | ||
|
||
func NewEncryptor(key []byte) (*Encryptor, error) { | ||
if len(key) != 32 { | ||
return nil, fmt.Errorf("key must be 32 bytes long") | ||
} | ||
|
||
block, err := aes.NewCipher(key) | ||
if err != nil { | ||
return nil, err | ||
} | ||
gcm, err := cipher.NewGCM(block) | ||
if err != nil { | ||
return nil, err | ||
} | ||
return &Encryptor{gcm: gcm, key: key}, nil | ||
} | ||
|
||
func (e *Encryptor) Encrypt(plaintext []byte) ([]byte, error) { | ||
nonce := make([]byte, e.gcm.NonceSize()) | ||
if _, err := io.ReadFull(rand.Reader, nonce); err != nil { | ||
return nil, err | ||
} | ||
return e.gcm.Seal(nonce, nonce, plaintext, nil), nil | ||
} | ||
|
||
func (e *Encryptor) Decrypt(ciphertext []byte) ([]byte, error) { | ||
if len(ciphertext) < e.gcm.NonceSize() { | ||
return nil, errors.New("ciphertext too short") | ||
} | ||
nonce, ciphertext := ciphertext[:e.gcm.NonceSize()], ciphertext[e.gcm.NonceSize():] | ||
return e.gcm.Open(nil, nonce, ciphertext, nil) | ||
} | ||
|
||
func (e *Encryptor) HashWithHMAC(data []byte) []byte { | ||
h := hmac.New(sha256.New, e.key) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can this be reused? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should not be reused (it has it's internal state and by reusing we might get different outputs) |
||
h.Write(data) | ||
return h.Sum(nil) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
package encryption | ||
|
||
import ( | ||
"bytes" | ||
"crypto/rand" | ||
"testing" | ||
) | ||
|
||
func TestNewEncryptor(t *testing.T) { | ||
key := make([]byte, 32) // 256-bit key | ||
_, err := rand.Read(key) | ||
if err != nil { | ||
t.Fatalf("Failed to generate random key: %v", err) | ||
} | ||
|
||
encryptor, err := NewEncryptor(key) | ||
if err != nil { | ||
t.Fatalf("NewEncryptor failed: %v", err) | ||
} | ||
|
||
if encryptor == nil { | ||
t.Fatal("NewEncryptor returned nil") | ||
} | ||
} | ||
|
||
func TestEncryptDecrypt(t *testing.T) { | ||
key := make([]byte, 32) // 256-bit key | ||
_, err := rand.Read(key) | ||
if err != nil { | ||
t.Fatalf("Failed to generate random key: %v", err) | ||
} | ||
|
||
encryptor, err := NewEncryptor(key) | ||
if err != nil { | ||
t.Fatalf("NewEncryptor failed: %v", err) | ||
} | ||
|
||
plaintext := []byte("Hello, World!") | ||
|
||
ciphertext, err := encryptor.Encrypt(plaintext) | ||
if err != nil { | ||
t.Fatalf("Encryption failed: %v", err) | ||
} | ||
|
||
decrypted, err := encryptor.Decrypt(ciphertext) | ||
if err != nil { | ||
t.Fatalf("Decryption failed: %v", err) | ||
} | ||
|
||
if !bytes.Equal(plaintext, decrypted) { | ||
t.Fatalf("Decrypted text does not match original plaintext") | ||
} | ||
} | ||
|
||
func TestEncryptDecryptEmptyString(t *testing.T) { | ||
key := make([]byte, 32) // 256-bit key | ||
_, err := rand.Read(key) | ||
if err != nil { | ||
t.Fatalf("Failed to generate random key: %v", err) | ||
} | ||
|
||
encryptor, err := NewEncryptor(key) | ||
if err != nil { | ||
t.Fatalf("NewEncryptor failed: %v", err) | ||
} | ||
|
||
plaintext := []byte("") | ||
|
||
ciphertext, err := encryptor.Encrypt(plaintext) | ||
if err != nil { | ||
t.Fatalf("Encryption of empty string failed: %v", err) | ||
} | ||
|
||
decrypted, err := encryptor.Decrypt(ciphertext) | ||
if err != nil { | ||
t.Fatalf("Decryption of empty string failed: %v", err) | ||
} | ||
|
||
if !bytes.Equal(plaintext, decrypted) { | ||
t.Fatalf("Decrypted empty string does not match original") | ||
} | ||
} | ||
|
||
func TestDecryptInvalidCiphertext(t *testing.T) { | ||
key := make([]byte, 32) // 256-bit key | ||
_, err := rand.Read(key) | ||
if err != nil { | ||
t.Fatalf("Failed to generate random key: %v", err) | ||
} | ||
|
||
encryptor, err := NewEncryptor(key) | ||
if err != nil { | ||
t.Fatalf("NewEncryptor failed: %v", err) | ||
} | ||
|
||
invalidCiphertext := []byte("This is not a valid ciphertext") | ||
|
||
_, err = encryptor.Decrypt(invalidCiphertext) | ||
if err == nil { | ||
t.Fatal("Decryption of invalid ciphertext should have failed, but didn't") | ||
} | ||
} | ||
|
||
func TestNewEncryptorInvalidKeySize(t *testing.T) { | ||
invalidKey := make([]byte, 31) // Invalid key size (not 16, 24, or 32 bytes) | ||
_, err := rand.Read(invalidKey) | ||
if err != nil { | ||
t.Fatalf("Failed to generate random key: %v", err) | ||
} | ||
|
||
_, err = NewEncryptor(invalidKey) | ||
if err == nil { | ||
t.Fatal("NewEncryptor should have failed with invalid key size, but didn't") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
please add a good comment describing the encryption approach. AES-GCM with key size, nonce size. How we generate a nonce for each.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
added a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks.