Skip to content

Instantly share code, notes, and snippets.

@mattatcha
Forked from josephspurrier/aescmd.go
Created October 30, 2016 03:05
Show Gist options
  • Save mattatcha/a0a26636c06a88092c452a9b9f3aaca4 to your computer and use it in GitHub Desktop.
Save mattatcha/a0a26636c06a88092c452a9b9f3aaca4 to your computer and use it in GitHub Desktop.
Golang - Encrypt, Decrypt, File Read, File Write, Readline
package main
import (
"bufio"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"fmt"
"io"
"io/ioutil"
"os"
)
func decrypt(cipherstring string, keystring string) string {
// Byte array of the string
ciphertext := []byte(cipherstring)
// Key
key := []byte(keystring)
// Create the AES cipher
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// Before even testing the decryption,
// if the text is too small, then it is incorrect
if len(ciphertext) < aes.BlockSize {
panic("Text is too short")
}
// Get the 16 byte IV
iv := ciphertext[:aes.BlockSize]
// Remove the IV from the ciphertext
ciphertext = ciphertext[aes.BlockSize:]
// Return a decrypted stream
stream := cipher.NewCFBDecrypter(block, iv)
// Decrypt bytes from ciphertext
stream.XORKeyStream(ciphertext, ciphertext)
return string(ciphertext)
}
func encrypt(plainstring, keystring string) string {
// Byte array of the string
plaintext := []byte(plainstring)
// Key
key := []byte(keystring)
// Create the AES cipher
block, err := aes.NewCipher(key)
if err != nil {
panic(err)
}
// Empty array of 16 + plaintext length
// Include the IV at the beginning
ciphertext := make([]byte, aes.BlockSize+len(plaintext))
// Slice of first 16 bytes
iv := ciphertext[:aes.BlockSize]
// Write 16 rand bytes to fill iv
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
panic(err)
}
// Return an encrypted stream
stream := cipher.NewCFBEncrypter(block, iv)
// Encrypt bytes from plaintext to ciphertext
stream.XORKeyStream(ciphertext[aes.BlockSize:], plaintext)
return string(ciphertext)
}
func readline() string {
bio := bufio.NewReader(os.Stdin)
line, _, err := bio.ReadLine()
if err != nil {
fmt.Println(err)
}
return string(line)
}
func writeToFile(data, file string) {
ioutil.WriteFile(file, []byte(data), 777)
}
func readFromFile(file string) ([]byte, error) {
data, err := ioutil.ReadFile(file)
return data, err
}
func main() {
key := "testtesttesttest"
for {
fmt.Print("What would you like to do? ")
line := readline()
switch line {
case "help":
fmt.Println("You can:\nencrypt\ndecrypt\nexit")
case "exit":
os.Exit(0)
case "encrypt":
fmt.Print("What would you like to encrypt: ")
line2 := readline()
ciphertext := encrypt(line2, key)
fmt.Print("What is the file name: ")
line3 := readline()
writeToFile(ciphertext, line3)
fmt.Println("Wrote to file")
case "decrypt":
fmt.Print("What is the name of the file to decrypt: ")
line2 := readline()
if ciphertext, err := readFromFile(line2); err != nil {
fmt.Println("File is not found")
} else {
plaintext := decrypt(string(ciphertext), key)
fmt.Println(plaintext)
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment