Skip to content
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

Added an encryption mechanism for API keys, Fixed the config syncing problem #229

Merged
merged 12 commits into from
Nov 4, 2021
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