Skip to content

Commit 9479107

Browse files
committed
Initial commit
0 parents  commit 9479107

File tree

6 files changed

+596
-0
lines changed

6 files changed

+596
-0
lines changed

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Idea files
2+
.idea/
3+
*.iml
4+
5+
build/
6+
7+
*.tar.gz

README.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Crypta2
2+
3+
Crypta2 uses anonymous encryption and decryption from [golang.org/x/crypto/nacl/box](https://godoc.org/golang.org/x/crypto/nacl/box) library to securely transfer your data.
4+
5+
## Getting Started
6+
7+
### Installation
8+
9+
#### Linux
10+
11+
1. Download
12+
13+
```bash
14+
curl -LO https://github.com/Mirage20/crypta2/releases/latest/download/crypta2-linux-x64.tar.gz
15+
```
16+
2. Extract
17+
18+
```bash
19+
tar -xzvf crypta2-linux-x64.tar.gz
20+
```
21+
3. Install
22+
23+
```bash
24+
sudo mv ./crypta2 /usr/local/bin/crypta2
25+
```
26+
27+
#### MacOS
28+
29+
1. Download
30+
31+
```bash
32+
curl -LO https://github.com/Mirage20/crypta2/releases/latest/download/crypta2-darwin-x64.tar.gz
33+
```
34+
2. Extract
35+
36+
```bash
37+
tar -xzvf crypta2-darwin-x64.tar.gz
38+
```
39+
3. Install
40+
41+
```bash
42+
sudo mv ./crypta2 /usr/local/bin/crypta2
43+
```
44+
45+
### Usage
46+
47+
1. Generate a key pair `my-key.pub` and `my-key.pvt`
48+
49+
```bash
50+
# The following command will generate a key pair and write it to current directory
51+
crypta2 genkey my-key
52+
```
53+
54+
2. Encrypt using public key
55+
56+
```bash
57+
# Encrypt message.txt using public key and save it as base64 encoded payload.txt
58+
crypta2 encrypt -f message.txt -p my-key.pub > payload.txt
59+
60+
# Read data from stdin pipe and encrypt
61+
echo "Hello World" | crypta2 encrypt -p my-key.pub > payload.txt
62+
63+
# Encrypt data from stdin and output to stdout (press Ctrl+D after entering the secret)
64+
crypta2 encrypt -p my-key.pub
65+
```
66+
67+
3. Decrypt using private and public key
68+
69+
```bash
70+
# Decrypt base64 encoded payload.txt using private key and save it as message.txt
71+
crypta2 decrypt -f payload.txt -k my-key.pvt -p my-key.pub > message.txt
72+
73+
# Decrypt data from stdin and output to stdout (press Ctrl+D after entering the input)
74+
crypta2 decrypt -k my-key.pvt -p my-key.pub
75+
```
76+
77+
4. Run `crypta2 --help` for more information
78+
79+
```text
80+
Usage:
81+
crypta2 [command]
82+
83+
Available Commands:
84+
decrypt Decrypt input with the given private and public keys
85+
encrypt Encrypt input with the given public key
86+
genkey Generates a key pair
87+
help Help about any command
88+
89+
Flags:
90+
-h, --help help for crypta2
91+
-v, --version version for crypta2
92+
93+
Use "crypta2 [command] --help" for more information about a command.
94+
95+
```

build.sh

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
3+
GIT_REVISION=$(git rev-parse --short --verify HEAD)
4+
TIME=$(date -u +%Y%m%d.%H%M%S)
5+
VERSION=1.0.${GIT_REVISION}.${TIME}
6+
7+
build_artifacts () {
8+
local os=$1
9+
local arch=$2
10+
GO111MODULE=on GOOS=$os GOARCH=$arch go build -ldflags "-X main.versionString=${VERSION}" ./cmd/crypta2/
11+
file crypta2
12+
tar -czvf crypta2-"$os"-x64.tar.gz crypta2
13+
rm crypta2
14+
}
15+
16+
build_artifacts linux amd64
17+
build_artifacts darwin amd64

cmd/crypta2/main.go

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
package main
2+
3+
import (
4+
"crypto/rand"
5+
"encoding/base64"
6+
"fmt"
7+
"github.com/spf13/cobra"
8+
"golang.org/x/crypto/nacl/box"
9+
"io/ioutil"
10+
"os"
11+
)
12+
13+
var (
14+
versionString string
15+
)
16+
17+
func main() {
18+
rootCmd := &cobra.Command{
19+
Use: "crypta2",
20+
Short: "Just another cryptographic tool",
21+
SilenceErrors: true,
22+
Version: versionString,
23+
}
24+
rootCmd.AddCommand(makeGenKeyCmd())
25+
rootCmd.AddCommand(makeEncryptCmd())
26+
rootCmd.AddCommand(makeDecryptCmd())
27+
if err := rootCmd.Execute(); err != nil {
28+
_, _ = fmt.Fprintln(os.Stderr, err)
29+
os.Exit(1)
30+
}
31+
}
32+
33+
func makeGenKeyCmd() *cobra.Command {
34+
cmdGenKey := &cobra.Command{
35+
Use: "genkey filename",
36+
Short: "Generates a key pair",
37+
Long: "Generates a key pair and save as filename.pub and filename.pvt to working directory",
38+
Args: cobra.ExactArgs(1),
39+
SilenceUsage: true,
40+
RunE: func(cmd *cobra.Command, args []string) error {
41+
fileNamePub := fmt.Sprintf("%s.pub", args[0])
42+
fileNamePvt := fmt.Sprintf("%s.pvt", args[0])
43+
44+
if _, err := os.Stat(fileNamePvt); err == nil {
45+
return fmt.Errorf("private key file %q already exists", fileNamePvt)
46+
}
47+
48+
if _, err := os.Stat(fileNamePub); err == nil {
49+
return fmt.Errorf("public key file %q already exists", fileNamePub)
50+
}
51+
52+
pubKey, pvtKey, err := box.GenerateKey(rand.Reader)
53+
if err != nil {
54+
return fmt.Errorf("cannot generate key pair: %v", err)
55+
}
56+
pubEncoded := []byte(base64.StdEncoding.EncodeToString(pubKey[:]))
57+
pvtEncoded := []byte(base64.StdEncoding.EncodeToString(pvtKey[:]))
58+
fmt.Printf("Writing public key %q\n", fileNamePub)
59+
60+
err = ioutil.WriteFile(fileNamePub, pubEncoded, 0644)
61+
if err != nil {
62+
return fmt.Errorf("cannot write public key %q: %v", fileNamePub, err)
63+
}
64+
65+
fmt.Printf("Writing private key %q\n", fileNamePvt)
66+
err = ioutil.WriteFile(fileNamePvt, pvtEncoded, 0600)
67+
if err != nil {
68+
return fmt.Errorf("cannot write private key %q: %v", fileNamePvt, err)
69+
}
70+
return nil
71+
},
72+
}
73+
return cmdGenKey
74+
}
75+
76+
func makeEncryptCmd() *cobra.Command {
77+
var input string
78+
var pubKeyFile string
79+
cmdEncrypt := &cobra.Command{
80+
Use: "encrypt [(-f|--file=) input] (-p|--public-key=) public-key file",
81+
Short: "Encrypt input with the given public key",
82+
Long: "Encrypt input file or stdin with the given public key",
83+
Args: cobra.ExactArgs(0),
84+
SilenceUsage: true,
85+
RunE: func(cmd *cobra.Command, args []string) error {
86+
inBytes, err := readInput(input)
87+
if err != nil {
88+
return fmt.Errorf("cannot read input: %v", err)
89+
}
90+
pubEnc, err := ioutil.ReadFile(pubKeyFile)
91+
if err != nil {
92+
return fmt.Errorf("cannot read public key file %q: %v", pubKeyFile, err)
93+
}
94+
pubBytes, err := base64.StdEncoding.DecodeString(string(pubEnc))
95+
if err != nil {
96+
return fmt.Errorf("cannot decode public key: %v", err)
97+
}
98+
99+
var pubKey32 [32]byte
100+
copy(pubKey32[:], pubBytes)
101+
102+
value, err := box.SealAnonymous(nil, inBytes, &pubKey32, nil)
103+
if err != nil {
104+
return fmt.Errorf("cannot encrypt the input with provided public key")
105+
}
106+
fmt.Println(base64.StdEncoding.EncodeToString(value))
107+
return nil
108+
},
109+
}
110+
111+
cmdEncrypt.Flags().StringVarP(&input, "file", "f", "", "Input file path. Uses standard input if not provided")
112+
cmdEncrypt.Flags().StringVarP(&pubKeyFile, "public-key", "p", "", "Public key file path for decrypting")
113+
_ = cmdEncrypt.MarkFlagRequired("public-key")
114+
return cmdEncrypt
115+
}
116+
117+
func makeDecryptCmd() *cobra.Command {
118+
var input string
119+
var pvtKeyFile string
120+
var pubKeyFile string
121+
cmdDecrypt := &cobra.Command{
122+
Use: "decrypt [(-f|--file=) input] (-k|--private-key=) private-key file (-p|--public-key=) public-key file",
123+
Short: "Decrypt input with the given private and public keys",
124+
Long: "Decrypt input file or stdin with the given private and public keys",
125+
Args: cobra.ExactArgs(0),
126+
SilenceUsage: true,
127+
RunE: func(cmd *cobra.Command, args []string) error {
128+
inEncodedBytes, err := readInput(input)
129+
if err != nil {
130+
return fmt.Errorf("cannot read input: %v", err)
131+
}
132+
inBytes, err := base64.StdEncoding.DecodeString(string(inEncodedBytes))
133+
if err != nil {
134+
return fmt.Errorf("cannot decode input: %v", err)
135+
}
136+
pubEnc, err := ioutil.ReadFile(pubKeyFile)
137+
if err != nil {
138+
return fmt.Errorf("cannot read public key file %q: %v", pubKeyFile, err)
139+
}
140+
pubBytes, err := base64.StdEncoding.DecodeString(string(pubEnc))
141+
if err != nil {
142+
return fmt.Errorf("cannot decode public key: %v", err)
143+
}
144+
pvtEnc, err := ioutil.ReadFile(pvtKeyFile)
145+
if err != nil {
146+
return fmt.Errorf("cannot read private key file %q: %v", pvtKeyFile, err)
147+
}
148+
pvtBytes, err := base64.StdEncoding.DecodeString(string(pvtEnc))
149+
if err != nil {
150+
return fmt.Errorf("cannot decode private key: %v", err)
151+
}
152+
var pubKey32 [32]byte
153+
var pvtKey32 [32]byte
154+
copy(pubKey32[:], pubBytes)
155+
copy(pvtKey32[:], pvtBytes)
156+
157+
value, ok := box.OpenAnonymous(nil, inBytes, &pubKey32, &pvtKey32)
158+
if !ok {
159+
return fmt.Errorf("cannot decrypt the input with provided key pair")
160+
}
161+
fmt.Println(string(value))
162+
return nil
163+
},
164+
}
165+
166+
cmdDecrypt.Flags().StringVarP(&input, "file", "f", "", "Base64 input file path. Uses standard input if not provided")
167+
cmdDecrypt.Flags().StringVarP(&pubKeyFile, "public-key", "p", "", "Public key file path for decrypting")
168+
cmdDecrypt.Flags().StringVarP(&pvtKeyFile, "private-key", "k", "", "Private key file path for decrypting")
169+
_ = cmdDecrypt.MarkFlagRequired("public-key")
170+
_ = cmdDecrypt.MarkFlagRequired("private-key")
171+
return cmdDecrypt
172+
}
173+
174+
func readInput(file string) ([]byte, error) {
175+
if len(file) > 0 {
176+
return ioutil.ReadFile(file)
177+
} else {
178+
return ioutil.ReadAll(os.Stdin)
179+
}
180+
}

go.mod

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module github.com/mirage20/crypta2
2+
3+
go 1.12
4+
5+
require (
6+
github.com/spf13/cobra v1.1.1
7+
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0
8+
)

0 commit comments

Comments
 (0)