Skip to content

Instantly share code, notes, and snippets.

@stefan2904
Created July 11, 2015 15:45
Show Gist options
  • Save stefan2904/77805131ad91869c5ca9 to your computer and use it in GitHub Desktop.
Save stefan2904/77805131ad91869c5ca9 to your computer and use it in GitHub Desktop.
Wanna talk with John? Join his supersecret communication channel. Of course it's secure, it uses a brand new hipster handmade cryptocipher! Amazingly unbreakable!
package main
import (
"crypto/des"
"crypto/cipher"
"crypto/rand"
"errors"
"io"
"fmt"
"log"
"net"
"os"
"bytes"
"encoding/hex"
)
const (
CONN_HOST = "0.0.0.0"
CONN_PORT = "8000"
CONN_TYPE = "tcp"
)
var suchSubstitution = [32]byte{
0, 1, 1, 0, 1, 0, 0, 1,
0, 1, 0, 0, 1, 1, 0, 1,
0, 0, 1, 1, 1, 0, 1, 0,
0, 1, 1, 0, 1, 1, 0, 0,
}
func main() {
ede2Key := []byte("<-- Some supersecret encryption key goes here -->")
// Create a new instance of our magic cipher. Wow.
tripleDOGESKey := muchSecurity(ede2Key)
muchCipher, err := NewTripleDOGESCipher(tripleDOGESKey)
if err != nil {
log.Fatal(err)
}
// Listen for incoming connections.
l, err := net.Listen(CONN_TYPE, CONN_HOST+":"+CONN_PORT)
if err != nil {
fmt.Println("Error listening:", err.Error())
os.Exit(1)
}
// Close the listener when the application closes.
defer l.Close()
fmt.Println("Listening on " + CONN_HOST + ":" + CONN_PORT)
for {
// Listen for an incoming connection.
conn, err := l.Accept()
if err != nil {
fmt.Println("Error accepting: ", err.Error())
os.Exit(1)
}
// Handle connections in a new goroutine.
go handleRequest(conn, muchCipher)
}
}
// Handles incoming requests.
func handleRequest(conn net.Conn, muchCipher cipher.Block) {
// Whoops.
superkey := []byte("<-- Some amazing program key goes here -->")
success := []byte("Amazing! Flag: <-- Some incredible flag goes here -->\n")
failure := []byte("JOHN IS ANGRY.\n")
// Print things.
plain := []byte("\nWelcome! Wanna talk with John? Follow the instructions to get a Secure™ Channel.\n")
cipherthings := make([]byte, 1024)
ciphertext := encrypt(plain, muchCipher)
hex.Encode(cipherthings, ciphertext)
plain = append(plain, cipherthings...)
conn.Write(plain)
plain = []byte("\n\nYou surely know what to do with this:\n")
cipherthings = make([]byte, 1024)
ciphertext = encrypt(superkey, muchCipher)
hex.Encode(cipherthings, ciphertext)
plain = append(plain, cipherthings...)
conn.Write(plain)
request := []byte("\n\nInsert key:\n")
conn.Write(request)
// Make a buffer to hold incoming data.
buf := make([]byte, 1024)
// Read the incoming connection into the buffer.
reqLen, err := conn.Read(buf)
if err != nil {
fmt.Println("Error reading:", err.Error())
}
// Send a response back to our friends.
if bytes.Contains(buf[:reqLen], superkey) {
conn.Write(success)
} else {
conn.Write(failure)
}
// Close the connection when you're done with it.
conn.Close()
}
func NewTripleDOGESCipher(tripleDOGESKey []byte) (cipher.Block, error) {
// I can't break it, so it is unbreakable. A friend told us so.
muchCipher, err := des.NewTripleDESCipher(tripleDOGESKey)
if err != nil {
return nil, err
}
return muchCipher, nil
}
func encrypt(text []byte, block cipher.Block) []byte {
if len(text)%des.BlockSize != 0 {
text = padSlice(text)
}
ciphertext := make([]byte, des.BlockSize+len(text))
iv := ciphertext[:des.BlockSize]
if _, err := io.ReadFull(rand.Reader, iv); err != nil {
log.Fatal(err)
}
mode := cipher.NewCBCEncrypter(block, iv)
mode.CryptBlocks(ciphertext[des.BlockSize:], text)
return ciphertext
}
func decrypt(text []byte, block cipher.Block) []byte {
if len(text) < des.BlockSize {
log.Fatal(errors.New("ciphertext too short"))
}
iv := text[:des.BlockSize]
text = text[des.BlockSize:]
// CBC mode always works in whole blocks.
if len(text)%des.BlockSize != 0 {
text = padSlice(text)
}
mode := cipher.NewCBCDecrypter(block, iv)
dst := make([]byte, len(text))
mode.CryptBlocks(dst, text)
return dst
}
func muchSecurity(key []byte) []byte {
var tripleDOGESKey []byte
secondKey := make([]byte, 16)
copy(secondKey, key)
for i := 8; i < 16; i++ {
// Let's be sure it is enough complex. Complex is good, a friend told us so.
key[i] = (secondKey[i] & 0x3c) | (suchSubstitution[(secondKey[i] >> 2) & 0x0f] << 6)
key[i] |= (key[i] >> 3) & 0x03
key[i] |= ((key[i] >> 4) ^ key[i]) << 7
}
// EDE2 is required.
tripleDOGESKey = append(tripleDOGESKey, key[:8]...)
return append(tripleDOGESKey, key[:16]...)
}
func padSlice(src []byte) []byte {
// src must be a multiple of block size.
bs := des.BlockSize
mult := int((len(src) / bs) + 1)
leng := bs * mult
src_padded := make([]byte, leng)
copy(src_padded, src)
return src_padded
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment