Created
July 11, 2015 15:45
-
-
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!
This file contains hidden or 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 ( | |
"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