|
package main |
|
|
|
import ( |
|
"crypto/aes" |
|
"crypto/cipher" |
|
"crypto/rand" |
|
"crypto/sha256" |
|
"fmt" |
|
"io" |
|
"os" |
|
"regexp" |
|
"slices" |
|
"strings" |
|
) |
|
|
|
func main() { |
|
fmt.Print("\n\033[1;34mPasskey : \033[0m") |
|
var keyString string |
|
fmt.Scan(&keyString) |
|
fmt.Println() |
|
|
|
h := sha256.New() |
|
h.Write([]byte(keyString)) |
|
key := h.Sum(nil) |
|
|
|
file := "./crypt.log"; |
|
plainText := "" |
|
cipherText, err := os.ReadFile(file) |
|
if err == nil { |
|
plainText, err = DecryptMessage(key, cipherText) |
|
if err != nil { panic(err) } |
|
} |
|
|
|
for { |
|
fmt.Print("\033[1;34mCommand : \033[0m") |
|
var command string |
|
fmt.Scan(&command) |
|
|
|
switch command { |
|
case "get": |
|
var arg string |
|
fmt.Scan(&arg) |
|
fmt.Println(strings.Join(regexp.MustCompile(`(?m)^` + arg + `(.*)?\n`).FindAllString(plainText, -1), "")) |
|
case "set": |
|
var argk string |
|
fmt.Scan(&argk) |
|
var argv string |
|
fmt.Scan(&argv) |
|
re := regexp.MustCompile(`(?m)^` + argk + ` (.*)?\n`) |
|
if re.MatchString(plainText) { |
|
plainText = re.ReplaceAllString(plainText, argk + " " + argv + "\n") |
|
} else { |
|
plainText += argk + " " + argv + "\n" |
|
} |
|
lines := strings.Split(plainText, "\n") |
|
lines = lines[:len(lines) - 1] |
|
slices.Sort(lines) |
|
plainText = strings.Join(lines, "\n") + "\n" |
|
fmt.Println() |
|
case "del": |
|
var arg string |
|
fmt.Scan(&arg) |
|
re := regexp.MustCompile(`(?m)^` + arg + ` (.*)?\n`) |
|
plainText = re.ReplaceAllString(plainText, "") |
|
fmt.Println() |
|
case "show": |
|
fmt.Println(plainText) |
|
case "list": |
|
re := regexp.MustCompile(` (.*)?\n`) |
|
fmt.Println(re.ReplaceAllString(plainText, "\n")) |
|
case "save": |
|
cipherText, err := EncryptMessage(key, plainText) |
|
if err != nil { panic(err) } |
|
err = os.WriteFile(file, cipherText, 0644) |
|
if err != nil { panic(err) } |
|
fmt.Println() |
|
case "quit": |
|
fmt.Println() |
|
return |
|
default: |
|
fmt.Println("Invalid Command\n") |
|
} |
|
} |
|
|
|
} |
|
|
|
func EncryptMessage(key []byte, message string) ([]byte, error) { |
|
byteMsg := []byte(message) |
|
block, err := aes.NewCipher(key) |
|
if err != nil { panic(err) } |
|
|
|
cipherText := make([]byte, aes.BlockSize+len(byteMsg)) |
|
iv := cipherText[:aes.BlockSize] |
|
_, err = io.ReadFull(rand.Reader, iv) |
|
if err != nil { panic(err) } |
|
|
|
// https://pkg.go.dev/crypto/cipher#NewCFBEncrypter |
|
stream := cipher.NewCFBEncrypter(block, iv) |
|
stream.XORKeyStream(cipherText[aes.BlockSize:], byteMsg) |
|
|
|
return cipherText, nil |
|
} |
|
|
|
func DecryptMessage(key []byte, cipherText []byte) (string, error) { |
|
block, err := aes.NewCipher(key) |
|
if err != nil { panic(err) } |
|
|
|
if len(cipherText) < aes.BlockSize { |
|
return "", fmt.Errorf("invalid ciphertext block size") |
|
} |
|
|
|
iv := cipherText[:aes.BlockSize] |
|
cipherText = cipherText[aes.BlockSize:] |
|
|
|
// https://pkg.go.dev/crypto/cipher#NewCFBDecrypter |
|
stream := cipher.NewCFBDecrypter(block, iv) |
|
stream.XORKeyStream(cipherText, cipherText) |
|
|
|
return string(cipherText), nil |
|
} |