Skip to content

Commit

Permalink
Added an encryption mechanism for API keys, Fixed the config syncing …
Browse files Browse the repository at this point in the history
…problem (#229)

* Fix email from mismatch between env and settings db (#175)

* Encrypt Infura and SparkPost API keys inside the databse (#1)

* updated websocket package version to solve the go sum checksum mismatch problem

* Add golang.org/x/tools to go.sum by go mod download

* Modify dependencies to fix go.sum

* Modify go.sum

* Modify go.sum

* Modify go.sum

* Fix tests dependency problem

* Add encryption secret key to the Makefile

* change the encryption secret key in makefile
  • Loading branch information
m-javani authored Nov 4, 2021
1 parent 1d6cea8 commit 2e20bb0
Show file tree
Hide file tree
Showing 11 changed files with 224 additions and 356 deletions.
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export [email protected]
export PROXEUS_DATA_DIR?=./data
export PROXEUS_DATABASE_ENGINE?=storm
export PROXEUS_DATABASE_URI?=mongodb://localhost:27017
export PROXEUS_ENCRYPTION_SECRET_KEY?=PleAsE_chAnGe_me_32_Characters++

#########################################################

Expand Down
16 changes: 9 additions & 7 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ require (
github.com/h2non/filetype v1.1.1
github.com/imkira/go-interpol v1.1.0 // indirect
github.com/jackpal/go-nat-pmp v1.0.2 // indirect
github.com/klauspost/compress v1.11.12 // indirect
github.com/labstack/gommon v0.3.0
github.com/mattn/go-colorable v0.1.8 // indirect
github.com/mattn/go-runewidth v0.0.10 // indirect
Expand All @@ -41,10 +40,10 @@ require (
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
go.etcd.io/bbolt v1.3.5 // indirect
go.mongodb.org/mongo-driver v1.5.0
go.mongodb.org/mongo-driver v1.7.3
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
golang.org/x/net v0.0.0-20210324051636-2c4c8ecb7826
golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 // indirect
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d
golang.org/x/sys v0.0.0-20211102061401-a2f17f7b995c // indirect
gopkg.in/gavv/httpexpect.v2 v2.2.0
gopkg.in/sourcemap.v1 v1.0.5 // indirect
)
Expand All @@ -54,10 +53,12 @@ require (
github.com/StackExchange/wmi v0.0.0-20210224194228-fe8f1750fd46 // indirect
github.com/VictoriaMetrics/fastcache v1.5.8 // indirect
github.com/aws/aws-sdk-go v1.38.3 // indirect
github.com/fasthttp/websocket v1.4.3 // indirect
github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect
github.com/go-bindata/go-bindata/v3 v3.1.3 // indirect
github.com/go-kit/kit v0.10.0 // indirect
github.com/go-ole/go-ole v1.2.5 // indirect
github.com/go-sql-driver/mysql v1.5.0 // indirect
github.com/golang/protobuf v1.5.1 // indirect
github.com/google/uuid v1.2.0 // indirect
github.com/karalabe/usb v0.0.0-20191104083709-911d15fe12a9 // indirect
Expand All @@ -79,13 +80,14 @@ require (
github.com/valyala/fasthttp v1.22.0 // indirect
github.com/valyala/fasttemplate v1.2.1 // indirect
github.com/wadey/gocovmerge v0.0.0-20160331181800-b5bfa59ec0ad // indirect
github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c // indirect
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
golang.org/x/image v0.0.0-20210220032944-ac19c3e999fb // indirect
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 // indirect
golang.org/x/mod v0.4.2 // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
golang.org/x/mod v0.5.1 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
golang.org/x/tools v0.1.0 // indirect
golang.org/x/tools v0.1.7 // indirect
google.golang.org/appengine v1.6.7 // indirect
gopkg.in/urfave/cli.v1 v1.22.5 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
Expand Down
364 changes: 38 additions & 326 deletions go.sum

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions main/main_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build coverage
// +build coverage

package main
Expand Down
1 change: 1 addition & 0 deletions storage/database/db/mongo_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build integration
// +build integration

package db
Expand Down
1 change: 1 addition & 0 deletions storage/database/db/storm_test.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build integration
// +build integration

package db
Expand Down
24 changes: 24 additions & 0 deletions storage/database/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,13 +60,37 @@ func (se *SettingsDB) Put(s *model.Settings) error {
if err != nil {
return err
}
secret := os.Getenv("PROXEUS_ENCRYPTION_SECRET_KEY")
s.InfuraApiKey, err = EncryptWithAES(secret, s.InfuraApiKey)
if err != nil {
return err
}
s.SparkpostApiKey, err = EncryptWithAES(secret, s.SparkpostApiKey)
if err != nil {
return err
}

return se.jf.Put(s)
}

// Get retrieves all settings from the database / file
func (se *SettingsDB) Get() (*model.Settings, error) {
var s model.Settings
err := se.jf.Get(&s)
if err != nil {
return &s, err
}

secret := os.Getenv("PROXEUS_ENCRYPTION_SECRET_KEY")
s.InfuraApiKey, err = DecryptWithAES(secret, s.InfuraApiKey)
if err != nil {
return &s, err
}
s.SparkpostApiKey, err = DecryptWithAES(secret, s.SparkpostApiKey)
if err != nil {
return &s, err
}

return &s, err
}

Expand Down
57 changes: 57 additions & 0 deletions storage/database/utils.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
package database

import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io"
"regexp"
"strings"

Expand Down Expand Up @@ -112,3 +119,53 @@ func commonMatcher(auth model.Auth, contains string, params *simpleQuery) []q.Ma
}
return matchers
}

func EncryptWithAES(secret, stringToEncrypt string) (string, error) {

key := []byte(secret)
plaintext := []byte(stringToEncrypt)

block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
aesGCM, err := cipher.NewGCM(block)
if err != nil {
panic(err.Error())
}
nonce := make([]byte, aesGCM.NonceSize())
if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
return "", err
}

ciphertext := aesGCM.Seal(nonce, nonce, plaintext, nil)
return fmt.Sprintf("%x", ciphertext), nil
}

func DecryptWithAES(secret, encryptedString string) (string, error) {

key := []byte(secret)
enc, _ := hex.DecodeString(encryptedString)

block, err := aes.NewCipher(key)
if err != nil {
return "", err
}
aesGCM, err := cipher.NewGCM(block)
if err != nil {
return "", err
}
nonceSize := aesGCM.NonceSize()
if len(enc) < nonceSize {
return "", errors.New("decrypted key is corrupted")
}
nonce, ciphertext := enc[:nonceSize], enc[nonceSize:]

plaintext, err := aesGCM.Open(nil, nonce, ciphertext, nil)
if err != nil {
return "", err
}

pt := string(plaintext)
return pt, nil
}
25 changes: 25 additions & 0 deletions storage/database/utils_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package database

import (
"testing"

. "github.com/onsi/gomega"
)

func TestUtils(t *testing.T) {
RegisterTestingT(t)
// cipher key
secretKey := "thisis32bitlongpassphraseimusing"

// plaintext
pt := "11165875f50c4b87a32a501afa79bf64"

c, err := EncryptWithAES(secretKey, pt)
Expect(err).To(BeNil())

// decrypt
decrepted, err := DecryptWithAES(secretKey, c)
Expect(err).To(BeNil())

Expect(decrepted).To(Equal(pt))
}
34 changes: 33 additions & 1 deletion sys/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,11 @@ func NewWithSettings(settingsFile string, initialSettings *model.Settings) (*Sys
me.AllowHttp = true
}

err = me.init(me.GetSettings())
dbSettings := me.GetSettings()
syncedSettings := me.syncDBSettingsWithEnv(dbSettings, initialSettings)
me.PutSettings(syncedSettings)

err = me.init(syncedSettings)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -354,3 +358,31 @@ func (me *System) Shutdown() {
}
me.closeDBs()
}

func (me *System) syncDBSettingsWithEnv(dbStng, envStng *model.Settings) *model.Settings {

if envStng.DataDir != "" && dbStng.DataDir != envStng.DataDir {
dbStng.DataDir = envStng.DataDir
}
if envStng.InfuraApiKey != "" && dbStng.InfuraApiKey != envStng.InfuraApiKey {
dbStng.InfuraApiKey = envStng.InfuraApiKey
}
if envStng.SparkpostApiKey != "" && dbStng.SparkpostApiKey != envStng.SparkpostApiKey {
dbStng.SparkpostApiKey = envStng.SparkpostApiKey
}
if envStng.BlockchainContractAddress != "" && dbStng.BlockchainContractAddress != envStng.BlockchainContractAddress {
dbStng.BlockchainContractAddress = envStng.BlockchainContractAddress
}
if envStng.AllowHttp != "" && dbStng.AllowHttp != envStng.AllowHttp {
dbStng.AllowHttp = strings.ToLower(envStng.AllowHttp)
}
if envStng.PlatformDomain != "" && dbStng.PlatformDomain != envStng.PlatformDomain {
dbStng.PlatformDomain = envStng.PlatformDomain
}
if envStng.EmailFrom != "" && dbStng.EmailFrom != envStng.EmailFrom {
dbStng.EmailFrom = envStng.EmailFrom
}

return dbStng

}
Loading

0 comments on commit 2e20bb0

Please sign in to comment.