Skip to content

Commit

Permalink
Add encrypt and decrypt helper cmd
Browse files Browse the repository at this point in the history
  • Loading branch information
nightfury1204 committed Nov 12, 2024
1 parent dcdca1f commit b8d72a6
Show file tree
Hide file tree
Showing 2 changed files with 167 additions and 0 deletions.
62 changes: 62 additions & 0 deletions pkg/cli/encrypt.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package cli

import (
"fmt"

"github.com/convox/rack/pkg/crypt"
"github.com/convox/rack/sdk"
"github.com/convox/stdcli"
)

func init() {
register("encrypt", "encrypt data using key", Encrypt, stdcli.CommandOptions{
Flags: []stdcli.Flag{
stdcli.StringFlag("key", "", "key"),
stdcli.StringFlag("data", "", "data"),
},
Usage: "",
})

register("decrypt", "decrypt data using key", Decrypt, stdcli.CommandOptions{
Flags: []stdcli.Flag{
stdcli.StringFlag("key", "", "key"),
stdcli.StringFlag("data", "", "data"),
},
Usage: "",
})
}

func Encrypt(_ sdk.Interface, c *stdcli.Context) error {

key := c.String("key")
data := c.String("data")

if key == "" || data == "" {
return fmt.Errorf("key and data must be non empty")
}

val, err := crypt.Encrypt(key, []byte(data))
if err != nil {
return err
}

fmt.Println(val)
return nil
}

func Decrypt(_ sdk.Interface, c *stdcli.Context) error {
key := c.String("key")
data := c.String("data")

if key == "" || data == "" {
return fmt.Errorf("key and data must be non empty")
}

val, err := crypt.Decrypt(key, data)
if err != nil {
return err
}

fmt.Println(string(val))
return nil
}
105 changes: 105 additions & 0 deletions pkg/crypt/helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package crypt

import (
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"io"

"github.com/pkg/errors"
"golang.org/x/crypto/nacl/secretbox"
)

const (
KeySize = 32
NonceSize = 24
)

type RandEnvelope struct {
Nonce *[NonceSize]byte
CipherText []byte
}

func OneWay(str string) string {
enc := sha256.Sum256([]byte(str))
return base64.StdEncoding.EncodeToString(enc[:])
}

func Encrypt(ekey string, data []byte) (string, error) {
key, err := decodeKey(ekey)
if err != nil {
return "", errors.WithStack(err)
}

nonce, err := generateNonce()
if err != nil {
return "", errors.WithStack(err)
}

var cipherText []byte
cipherText = secretbox.Seal(cipherText, data, nonce, key)

envelope := RandEnvelope{
Nonce: nonce,
CipherText: cipherText,
}

envelopeJson, err := json.Marshal(envelope)
if err != nil {
return "", errors.WithStack(err)
}

return base64.StdEncoding.EncodeToString(envelopeJson), nil
}

func Decrypt(ekey string, sealed string) ([]byte, error) {
decoded, err := base64.StdEncoding.DecodeString(sealed)
if err != nil {
return nil, errors.WithStack(err)
}

var envelope RandEnvelope

if err := json.Unmarshal(decoded, &envelope); err != nil {
return nil, errors.WithStack(err)
}

key, err := decodeKey(ekey)
if err != nil {
return nil, errors.WithStack(err)
}

data := []byte{}

data, ok := secretbox.Open(nil, envelope.CipherText, envelope.Nonce, key)
if !ok {
return nil, errors.WithStack(fmt.Errorf("could not decrypt data"))
}

return data, nil
}

func decodeKey(ekey string) (*[KeySize]byte, error) {
var key [KeySize]byte

data, err := base64.StdEncoding.DecodeString(ekey)
if err != nil {
return nil, errors.WithStack(err)
}

copy(key[:], data[0:KeySize])

return &key, nil
}

func generateNonce() (*[NonceSize]byte, error) {
nonce := new([NonceSize]byte)
_, err := io.ReadFull(rand.Reader, nonce[:])
if err != nil {
return nil, errors.WithStack(err)
}

return nonce, nil
}

0 comments on commit b8d72a6

Please sign in to comment.