Created
November 30, 2016 22:19
-
-
Save slickplaid/0ab79d71b68118874acafbb52ff14c9a to your computer and use it in GitHub Desktop.
Encrypt and split, join and decrypt to help bypass pesky email filters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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