Skip to content

Commit

Permalink
add: cipher, fs and exit util, commands
Browse files Browse the repository at this point in the history
  • Loading branch information
nomionz committed Jan 26, 2024
1 parent b97e7ac commit 50b90ed
Show file tree
Hide file tree
Showing 9 changed files with 236 additions and 0 deletions.
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,20 @@
# fs-enc
CLI tool to encrypt and decrypt files with passphrase

## Why?

One of my use cases is to encrypt files stored in the **home** directory that may contain sensitive information.

I don't need to encrypt the whole file system, just a couple of files.

## Usage

## Encrypt
```bash
fs-enc enc <filepath> <passphrase>
```

## Decrypt
```bash
fs-enc dec <filepath> <passphrase>
```
24 changes: 24 additions & 0 deletions cmd/decrypt/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package decrypt

import (
"github.com/nomionz/fs-enc/pkg/fs"
"github.com/nomionz/fs-enc/pkg/util"
"github.com/spf13/cobra"
)

func Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "dec [file path] [passphrase]",
Short: "Decrypt the file",
Long: `Decrypt the file at the given path using the provided passphrase.`,
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
path := args[0]
passphrase := args[1]

util.ExitOnError(fs.Decrypt(path, []byte(passphrase)))
},
}

return cmd
}
24 changes: 24 additions & 0 deletions cmd/encrypt/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package encrypt

import (
"github.com/nomionz/fs-enc/pkg/fs"
"github.com/nomionz/fs-enc/pkg/util"
"github.com/spf13/cobra"
)

func Cmd() *cobra.Command {
cmd := &cobra.Command{
Use: "enc [file path] [passphrase]",
Short: "Encrypt the file",
Long: `Encrypt the file at the given path using the provided passphrase.`,
Args: cobra.ExactArgs(2),
Run: func(cmd *cobra.Command, args []string) {
path := args[0]
passphrase := args[1]

util.ExitOnError(fs.Encrypt(path, []byte(passphrase)))
},
}

return cmd
}
11 changes: 11 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module github.com/nomionz/fs-enc

go 1.21.2

require golang.org/x/crypto v0.18.0

require (
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
)
12 changes: 12 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0=
github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
20 changes: 20 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package main

import (
"github.com/nomionz/fs-enc/cmd/decrypt"
"github.com/nomionz/fs-enc/cmd/encrypt"
"github.com/nomionz/fs-enc/pkg/util"
"github.com/spf13/cobra"
)

func main() {
cmd := &cobra.Command{
Use: "",
}

cmd.CompletionOptions.HiddenDefaultCmd = true

cmd.AddCommand(encrypt.Cmd(), decrypt.Cmd())

util.ExitOnError(cmd.Execute())
}
74 changes: 74 additions & 0 deletions pkg/cipher/cipher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package cipher

import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"crypto/sha512"
"fmt"
"golang.org/x/crypto/pbkdf2"
"io"
)

const (
keyLen = 32
saltSize = 8
iterations = 1000
)

func Encrypt(data, pass []byte) ([]byte, error) {
salt := make([]byte, saltSize)

if _, err := rand.Read(salt); err != nil {
return nil, err
}

gcm, err := newCipher(pass, salt)
if err != nil {
return nil, err
}

nonce := make([]byte, gcm.NonceSize())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, err
}

encrypted := gcm.Seal(nonce, nonce, data, nil)
encrypted = append(salt, encrypted...)

return encrypted, nil
}

func Decrypt(data, pass []byte) ([]byte, error) {
salt := data[:saltSize]
data = data[saltSize:]

gcm, err := newCipher(pass, salt)
if err != nil {
return nil, err
}

nsize := gcm.NonceSize()
if len(data) < nsize {
return nil, fmt.Errorf("data size and nonce size don't match")
}

nonce, txt := data[:nsize], data[nsize:]

return gcm.Open(nil, nonce, txt, nil)
}

func deriveKey(pass, salt []byte) []byte {
return pbkdf2.Key(pass, salt, iterations, keyLen, sha512.New)
}

func newCipher(pass, salt []byte) (cipher.AEAD, error) {
key := deriveKey(pass, salt)

block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}

return cipher.NewGCM(block)
}
38 changes: 38 additions & 0 deletions pkg/fs/fs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package fs

import (
"github.com/nomionz/fs-enc/pkg/cipher"
"os"
)

func Decrypt(path string, pass []byte) error {
file, err := os.ReadFile(path)

if err != nil {
return err
}

dec, err := cipher.Decrypt(file, pass)

if err != nil {
return err
}

return os.WriteFile(path, dec, 0644)
}

func Encrypt(path string, pass []byte) error {
file, err := os.ReadFile(path)

if err != nil {
return err
}

enc, err := cipher.Encrypt(file, pass)

if err != nil {
return err
}

return os.WriteFile(path, enc, 0644)
}
15 changes: 15 additions & 0 deletions pkg/util/exit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package util

import (
"fmt"
"os"
)

func ExitOnError(err error) {
if err == nil {
return
}

fmt.Println(err)
os.Exit(1)
}

0 comments on commit 50b90ed

Please sign in to comment.