Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ sensitive data to the Filecoin network.

Encloud Encryption and Storage CLI is a lightweight utility that allows clients to

- Generate their RSA encryption keys
- Generate their ECIES/RSA encryption keys
- Manage file and encryption metadata in a local or remote KV store
- Upload encrypted files to Filecoin
- Retrieve encrypted files from Filecoin and decrypt them
Expand Down Expand Up @@ -37,7 +37,7 @@ go install .
```

## Command reference
1) Generate RSA 2048 key pair (key encryption key or KEK) to encrypt & decrypt the AES-256 keys (data encryption key or DEK). Run below command from the root of the project to the RSA key pair
1) Generate ECIES secp256k1 OR RSA 2048 key pair (key encryption key or KEK) to encrypt & decrypt the AES-256 keys (data encryption key or DEK). Run below command from the root of the project to the ECIES/RSA key pair
> encloud generate-key-pair

2) Upload encrypted data to Filecoin. This command encrypts the specified file using a newly generated DEK. The DEK is encrypted using the KEK and the metadata is stored on the local KV store.
Expand Down
20 changes: 16 additions & 4 deletions cmd/generate_key_pair.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package cmd

import (
"encloud/config"
thirdparty "encloud/third_party"
"encloud/types"
"encoding/json"
Expand All @@ -17,15 +18,26 @@ func GenerateKeyPairCmd() *cobra.Command {
Short: "Generate your key pair",
Long: `Generate your public key and private key which helps to encrypt and decrypt your data`,
Run: func(cmd *cobra.Command, args []string) {
thirdparty.InitCrypto()
cfg, _ := config.LoadConf("./config.yaml")
var keys types.Keys
if cfg.Stat.KekType == "rsa" {
thirdparty.InitCrypto()
keys = types.Keys{PublicKey: thirdparty.GetIdRsaPubStr(), PrivateKey: thirdparty.GetIdRsaStr()}
os.Remove(".keys/.idRsaPub")
os.Remove(".keys/.idRsa")
} else if cfg.Stat.KekType == "ecies" {
k := thirdparty.EciesGenerateKeyPair()
keys = types.Keys{PublicKey: k.PublicKey.Hex(false), PrivateKey: k.Hex()}
} else {
fmt.Fprintf(cmd.OutOrStderr(), "Invalid argument")
return
}
response := types.GenerateKeyPairResponse{
Status: "success",
StatusCode: http.StatusCreated,
Message: "Keys generated successfully.",
Data: types.Keys{PublicKey: thirdparty.GetIdRsaPubStr(), PrivateKey: thirdparty.GetIdRsaStr()},
Data: keys,
}
os.Remove(".keys/.idRsaPub")
os.Remove(".keys/.idRsa")
encoded, err := json.MarshalIndent(response, "", " ")
if err != nil {
fmt.Println(err)
Expand Down
23 changes: 18 additions & 5 deletions cmd/retrieve_by_cid.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,32 @@ func RetrieveByCidCmd() *cobra.Command {
}

fileMetaData := dbService.FetchByCid(thirdparty.DigestString(kek) + ":" + uuid)
decryptedDek, err := thirdparty.DecryptWithRSA(fileMetaData.Dek, thirdparty.GetIdRsaFromStr(privateKey))
if err != nil {
fmt.Println(err)
var decryptedDek []byte
if fileMetaData.KekType == "rsa" {
rsaKey, err := thirdparty.DecryptWithRSA(fileMetaData.Dek, thirdparty.GetIdRsaFromStr(privateKey))
if err != nil {
fmt.Println(err)
}
decryptedDek = rsaKey
} else if fileMetaData.KekType == "ecies" {
rsaKey, err := thirdparty.DecryptWithEcies(thirdparty.NewPrivateKeyFromHex(privateKey), fileMetaData.Dek)
if err != nil {
fmt.Println("err" + err.Error())
}
decryptedDek = rsaKey
} else {
fmt.Fprintf(cmd.OutOrStderr(), "Invalid argument")
return
}

filepath := estuaryService.DownloadContent(fileMetaData.Cid[0])
if fileMetaData.DekType == "aes" {
err = thirdparty.DecryptWithAES(decryptedDek, filepath, "assets/decrypted.csv")
err := thirdparty.DecryptWithAES(decryptedDek, filepath, "assets/decrypted.csv")
if err != nil {
fmt.Println(err)
}
} else {
err = thirdparty.DecryptWithChacha20poly1305(decryptedDek, filepath, "assets/decrypted.csv")
err := thirdparty.DecryptWithChacha20poly1305(decryptedDek, filepath, "assets/decrypted.csv")
if err != nil {
fmt.Println(err)
}
Expand Down
21 changes: 17 additions & 4 deletions cmd/share.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,26 @@ func ShareCmd() *cobra.Command {
}

fileMetaData := dbService.FetchByCid(thirdparty.DigestString(kek) + ":" + uuid)
decryptedDek, err := thirdparty.DecryptWithRSA(fileMetaData.Dek, thirdparty.GetIdRsaFromStr(privateKey))
if err != nil {
fmt.Println(err)
var decryptedDek []byte
if fileMetaData.KekType == "rsa" {
rsaKey, err := thirdparty.DecryptWithRSA(fileMetaData.Dek, thirdparty.GetIdRsaFromStr(privateKey))
if err != nil {
fmt.Println(err)
}
decryptedDek = rsaKey
} else if fileMetaData.KekType == "ecies" {
rsaKey, err := thirdparty.DecryptWithEcies(thirdparty.NewPrivateKeyFromHex(privateKey), fileMetaData.Dek)
if err != nil {
fmt.Println("err" + err.Error())
}
decryptedDek = rsaKey
} else {
fmt.Fprintf(cmd.OutOrStderr(), "Invalid argument")
return
}

// Writing decryption dek
err = ioutil.WriteFile("assets/dek.txt", decryptedDek, 0777)
err := ioutil.WriteFile("assets/dek.txt", decryptedDek, 0777)
if err != nil {
log.Fatalf("write file err: %v", err.Error())
}
Expand Down
19 changes: 15 additions & 4 deletions cmd/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,23 @@ func UploadContentCmd() *cobra.Command {
cids = append(cids, content.CID)

if cids != nil {
encryptedDek, err := thirdparty.EncryptWithRSA(dek, thirdparty.GetIdRsaPubFromStr(kek))
if err != nil {
fmt.Println("err" + err.Error())
var encryptedDek []byte
if cfg.Stat.KekType == "rsa" {
encryptedDek, err = thirdparty.EncryptWithRSA(dek, thirdparty.GetIdRsaPubFromStr(kek))
if err != nil {
fmt.Println("err" + err.Error())
}
} else if cfg.Stat.KekType == "ecies" {
encryptedDek, err = thirdparty.EncryptWithEcies(thirdparty.NewPublicKeyFromHex(kek), dek)
if err != nil {
fmt.Println("err" + err.Error())
}
} else {
fmt.Fprintf(cmd.OutOrStderr(), "Invalid argument")
return
}
hash := thirdparty.DigestString(kek)
fileData := types.FileMetadata{Timestamp: timestamp, Name: fileInfo.Name(), Size: int(fileInfo.Size()), FileType: filepath.Ext(fileInfo.Name()), Dek: encryptedDek, Cid: cids, Uuid: uuid, Md5Hash: hash, DekType: dekType}
fileData := types.FileMetadata{Timestamp: timestamp, Name: fileInfo.Name(), Size: int(fileInfo.Size()), FileType: filepath.Ext(fileInfo.Name()), Dek: encryptedDek, Cid: cids, Uuid: uuid, Md5Hash: hash, DekType: dekType, KekType: cfg.Stat.KekType}
dbService.Store(hash+":"+uuid, fileData)
}

Expand Down
9 changes: 5 additions & 4 deletions config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
estuary:
base_api_url: 'https://api.estuary.tech'
download_api_url: 'https://dweb.link/ipfs'
shuttle_api_url: 'https://shuttle-4.estuary.tech'
base_api_url: "https://api.estuary.tech"
download_api_url: "https://dweb.link/ipfs"
shuttle_api_url: "https://shuttle-4.estuary.tech"
token: EST6315eb22-5c76-4d47-9b75-1acb4a954070ARY
email:
server: smtp.mailtrap.io
Expand All @@ -10,7 +10,8 @@ email:
password: 861b495c076713
from: noreply@bond180.com
stat:
storageType: couchbase
kekType: ecies
storageType: badgerdb
badgerdb:
path: badger.db
couchbase:
Expand Down
3 changes: 3 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ email:
password: 861b495c076713
from: noreply@bond180.com
stat:
kekType: ecies
storageType: badgerdb
badgerdb:
path: badger.db
Expand Down Expand Up @@ -77,6 +78,7 @@ type SectionStat struct {
BadgerDB SectionBadgerDB `yaml:"badgerdb"`
Couchbase SectionCouchbase `yaml:"couchbase"`
StorageType string `yaml:"storageType"`
KekType string `yaml:"kekType"`
}

// SectionBadgerDB is sub section of config.
Expand Down Expand Up @@ -142,6 +144,7 @@ func LoadConf(confPath ...string) (*ConfYaml, error) {
conf.Email.Port = viper.GetInt64("email.port")

// Stat Engine
conf.Stat.KekType = viper.GetString("stat.kekType")
conf.Stat.StorageType = viper.GetString("stat.storageType")
conf.Stat.BadgerDB.Path = viper.GetString("stat.badgerdb.path")
conf.Stat.Couchbase.Host = viper.GetString("stat.couchbase.host")
Expand Down
9 changes: 5 additions & 4 deletions config/testdata/config.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
estuary:
base_api_url: 'https://api.estuary.tech'
download_api_url: 'https://dweb.link/ipfs'
shuttle_api_url: 'https://shuttle-4.estuary.tech'
base_api_url: "https://api.estuary.tech"
download_api_url: "https://dweb.link/ipfs"
shuttle_api_url: "https://shuttle-4.estuary.tech"
token: EST6315eb22-5c76-4d47-9b75-1acb4a954070ARY
email:
server: smtp.mailtrap.io
Expand All @@ -10,7 +10,8 @@ email:
password: 861b495c076713
from: noreply@bond180.com
stat:
storageType: couchbase
kekType: ecies
storageType: badgerdb
badgerdb:
path: badger.db
couchbase:
Expand Down
19 changes: 19 additions & 0 deletions docs/CONFIG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@ estuary:
token: "XXXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
```

## Key Encryption Key

Encloud CLI Encryption and Storage CLI offers supports for both RSA and ECIES type asymmetric encryption schemes for the
Key Encryption Key as part of the envelope encryption mechanism.

This can be easily configured in the [config.yaml](../config.yaml) as follows under the `estuary` section:

```yaml
stat:
kekType: ecies
```

Use `rsa` or `ecies`. Even though Encloud utilizes RSA-2048-OAEP, which is also used by major Web2 CSPs, there are known
vulnerabilities in its security and longevity. The KEK being the key encrypting all metadata, it is important that the KEK
follows best practices regarding longevity and security. ECIES encryption is considered more secure and offer better longevity.

ECIES is additionally supported by decentralized key custody solutions and users can leverage decentralized custody if they
choose ECIES scheme.

## Storage

### BadgerDB
Expand Down
2 changes: 1 addition & 1 deletion docs/DESIGN.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ a need for privacy tooling that can help onboard sensitive data sets in encrypte

The Encloud Encryption and Storage CLI was designed to meet the encryption requirements for the Filecoin ecosystem:

* Key Wrapping with RSA Key Encryption Keys (KEKs) and either AES-256 GCM or ChaCha20 Data Encryption Keys (DEKs)
* Key Wrapping with ECIES secp256k1/RSA Key Encryption Keys (KEKs) and either AES-256 GCM or ChaCha20 Data Encryption Keys (DEKs)
* DEK for each file generated
* Management of file and encryption metadata in a KV store (local or decentralized)
* Upload encrypted files to Filecoin
Expand Down
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,24 @@ go 1.18
require (
github.com/couchbase/gocb/v2 v2.6.0
github.com/dgraph-io/badger/v3 v3.2103.3
github.com/ecies/go/v2 v2.0.4
github.com/google/uuid v1.3.0
github.com/shirou/gopsutil/v3 v3.22.9
github.com/spf13/cobra v1.6.1
github.com/spf13/viper v1.13.0
github.com/stretchr/testify v1.8.1
golang.org/x/crypto v0.0.0-20220411220226-7b82a4e95df4
golang.org/x/crypto v0.0.0-20220507011949-2cf3adece122
)

require (
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/couchbase/gocbcore/v10 v10.2.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/ethereum/go-ethereum v1.10.17 // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
Expand Down
Loading