Skip to content

Instantly share code, notes, and snippets.

@slickplaid
Created November 30, 2016 22:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save slickplaid/0ab79d71b68118874acafbb52ff14c9a to your computer and use it in GitHub Desktop.
Save slickplaid/0ab79d71b68118874acafbb52ff14c9a to your computer and use it in GitHub Desktop.
Encrypt and split, join and decrypt to help bypass pesky email filters
package main
import (
"bufio"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"fmt"
"io"
"io/ioutil"
"math"
"os"
"strconv"
"strings"
)
func Split(f string) {
file, err := os.Open(f)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
defer file.Close()
fileInfo, _ := file.Stat()
var fileSize int64 = fileInfo.Size()
const fileChunk = 10 * (1 << 20)
totalPartsNum := uint64(math.Ceil(float64(fileSize) / float64(fileChunk)))
fmt.Printf("Splitting into %d pieces.\n", totalPartsNum)
for i := uint64(0); i < totalPartsNum; i++ {
partSize := int(math.Min(fileChunk, float64(fileSize-int64(i*fileChunk))))
partBuffer := make([]byte, partSize)
file.Read(partBuffer)
fileName := "part" + strconv.FormatUint(i, 10) + ".txt"
_, err := os.Create(fileName)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
ioutil.WriteFile(fileName, partBuffer, os.ModeAppend)
fmt.Println(fileName)
}
}
func SplitBuffer(buf []byte) {
var fileSize int64 = int64(len(buf))
const fileChunk = 10 * (1 << 20) // 10mb
totalPartsNum := uint64(math.Ceil(float64(fileSize) / float64(fileChunk)))
fmt.Printf("Splitting into %d pieces.\n", totalPartsNum)
for i := uint64(0); i < totalPartsNum; i++ {
//partSize := int(math.Min(fileChunk, float64(fileSize-int64(i*fileChunk))))
p := uint64(fileChunk)
start := i * fileChunk
end := (i + 1) * p
partBuffer := buf[start:]
//fmt.Println(start, end, len(buf), uint64(len(buf)))
if end < uint64(len(buf)) {
partBuffer = buf[start:end]
}
fileName := "part" + strconv.FormatUint(i, 10) + ".txt"
_, err := os.Create(fileName)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
ioutil.WriteFile(fileName, partBuffer, os.ModeAppend)
fmt.Println(fileName)
}
}
func min(a, b uint64) uint64 {
if a <= b {
return a
}
return b
}
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 appendToFile(file string, text string) {
f, err := os.OpenFile(file, os.O_APPEND|os.O_WRONLY, 0600)
if err != nil {
panic(err)
}
defer f.Close()
if _, err = f.WriteString(text); err != nil {
panic(err)
}
}
func Join() {
i := uint64(0)
f, err := os.OpenFile("out", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
f.Close()
fmt.Println(err)
return
}
for {
fileName := "part" + strconv.FormatUint(i, 10) + ".txt"
data, err := readFromFile(fileName)
if err != nil {
break
}
fmt.Println(fileName)
_, err = f.Write(data)
if err != nil {
fmt.Println(err)
break
}
i = i + 1
}
f.Close()
}
func main() {
prg := os.Args[0]
args := os.Args[1:]
if len(args) != 2 {
fmt.Println("Usage: " + prg + " <split|join|encrypt|decrypt|help> <file>")
os.Exit(1)
}
cmd := args[0]
input := args[1]
key := "s0a98f6ve0f60asf80awe98fa0w8e6=="
switch cmd {
case "help":
fmt.Println("\nsplit - Encrypt and split file into 10mb chunks. Usage: " + prg + " split input.exe")
fmt.Println("\njoin - Join files (partN.txt) and decrypt. Usage: " + prg + " split output.exe")
fmt.Println("\nencrypt - Encrypt file. Usage: " + prg + " split example.exe")
fmt.Println("\ndecrypt - Decrypt file. Usage: " + prg + " split example.exe")
main()
case "split":
file, err := readFromFile(input)
if err != nil {
fmt.Println(err)
break
}
ciphertext := encrypt(string(file[:]), key)
SplitBuffer([]byte(ciphertext))
case "join":
var ciphertext []byte
i := uint64(0)
for {
fileName := "part" + strconv.FormatUint(i, 10) + ".txt"
data, err := readFromFile(fileName)
if err != nil {
break
}
fmt.Println(fileName)
ciphertext = append(ciphertext, data...)
i = i + 1
}
plaintext := decrypt(string(ciphertext), key)
writeToFile(plaintext, input)
case "encrypt":
file, err := readFromFile(input)
if err != nil {
fmt.Println(err)
break
}
ciphertext := encrypt(string(file[:]), key)
writeToFile(ciphertext, input+"-enc")
fmt.Println("Wrote to file")
case "decrypt":
if ciphertext, err := readFromFile(input); err != nil {
fmt.Println("File is not found")
} else {
plaintext := decrypt(string(ciphertext), key)
writeToFile(plaintext, strings.TrimSuffix(input, "-enc")+"-dec")
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment