A 55: XOR Encryption in Go (120 pts)

What You Need

A Linux machine with Go installed, which you prepared in a previous project.

Purpose

Encrypt and decrypt files using XOR in Go.

Understanding XOR

Exclusive OR (XOR) is a fundamental mathematical operation used in many encryption algorithms.

XOR operates on one bit at a time, with these results:

0 XOR 0 = 0
0 XOR 1 = 1
1 XOR 0 = 1
1 XOR 1 = 0
For our purposes, we'll use the Go ^ operator, which acts on a whole byte at a time.

Characters are ASCII-encoded, like this:

A is 01000001
B is 01000010
C is 01000011
...
A whole table of ASCII values is here:

http://www.asciitable.com/

Consider A^B:

A is 01000001
B is 01000010
A^B= 00000011
That is character 3, an unprintable end-of-text mark.

However, A^s is printable:

A is 01000001
s is 01110011
A^B= 00110010
The result is the hexadecimal value 0x32, or the numeral 2.

XOR in Go

On your Linux server, in a Terminal window, execute these commands:
mkdir -p work/src/my_project/xor1
nano ~/work/src/my_project/xor1/xor1.go
In nano, enter this code, as shown below.
package main
import "fmt"

func main() {
    plaintext := "ABC"
    key := byte('s')
	ciphertext := ""
	n := 0

	for i, c := range plaintext {
		nc := byte(c)
		ciphertext += string( nc ^ key )
		n = i
	}
    fmt.Printf("Key:    \tHex: %x \tString: %s \tDecimal: %d\n",
    	key, string(key), key)
    fmt.Printf("Input:  \tHex: %x \tString: %s \n",
    	plaintext, plaintext)
    fmt.Printf("Output: \tHex: %x \tString: %s \t%d characters\n",
    	 ciphertext, ciphertext, n+1)
}

Save the file with Ctrl+X, Y, Enter.

Execute these commands to compile the program and run it:

go install my_project/xor1
xor1
The program runs, showing the key, input, and output in hexadecimal and string forms, as shown below.

Decrypting XOR in Go

To decrypt XOR-encrypted text, simply repeat the XOR operation again with the same key.

On your Linux server, in a Terminal window, execute these commands:

mkdir -p work/src/my_project/xor2
nano ~/work/src/my_project/xor2/xor2.go
In nano, enter this code, as shown below.
package main
import "fmt"

func main() {
    plaintext := "210"
    key := byte('s')
	ciphertext := ""
	n := 0

	for i, c := range plaintext {
		nc := byte(c)
		ciphertext += string( nc ^ key )
		n = i
	}
    fmt.Printf("Key:    \tHex: %x \tString: %s \tDecimal: %d\n",
    	key, string(key), key)
    fmt.Printf("Input:  \tHex: %x \tString: %s \n",
    	plaintext, plaintext)
    fmt.Printf("Output: \tHex: %x \tString: %s \t%d characters\n",
    	 ciphertext, ciphertext, n+1)
}
Save the file with Ctrl+X, Y, Enter.

Execute these commands to compile the program and run it:

go install my_project/xor2
xor2
The program runs, reversing the ciphertext "012" back to "ABC", as shown below.


A 55.1: Decrypting Ciphertext With the Key (5 pts)

Decrypt this ciphertext to reveal the flag:
232835272d2831312433
With a key of a

Hint: to put raw hex into a string, use \x characters like this:

ciphertext = "\x41\x42\x43\x44"

A 55.2: Decrypting Ciphertext Without the Key (10 pts)

Decrypt this ciphertext to reveal the flag:
150b070a0a190d031f1516070503
The key is a capital letter, from A to Z.


A 55.3: Decrypting Ciphertext Without the Key (15 pts)

Decrypt this ciphertext to reveal the flag:
6e6d04101e0208
The key is a byte, between 0 and 255.

A 55.4: Decrypting a Text File Without the Key (20 pts)

To get the ciphertext, execute this command:
wget https://bowneconsultingcontent.com/pub/Attack/proj/A55.4_infile

A 55.5: Decrypting an Image File Without the Key (20 pts)

To get the ciphertext, execute this command:
wget https://bowneconsultingcontent.com/pub/Attack/proj/A55.5_infile
The key is a byte, between 0 and 255.

This is an image file. When decrypted, it starts with a PNG file header, as shown below:

Notice that the first 4 bytes are 89, 50, 4E, 47; the 2nd through 4th byte spell out PNG in ASCII.

Decrypt the file. When you get it, change its filename extension to PNG and open it in an image viewer or Web browser.

The flag is visible in the image.


A 55.6: Two-Byte Key (20 pts)

The key is two bytes from \x0000 to \xffff.

During encryption, 16 bytes of plaintext are processed at a time, XORed with the 16 bytes of key.

To get the ciphertext, execute this command:

wget https://bowneconsultingcontent.com/pub/Attack/proj/A55.6_infile
This is an image file. When decrypted, it starts with a PNG file header, as in the previous challenge.

Decrypt the file. When you get it, change its filename extension to PNG and open it in an image viewer or Web browser.

The flag is visible in the image.


A 55.7: Multi-Byte Key (30 pts)

The key is a common English word.

To get the ciphertext, execute this command:

wget https://bowneconsultingcontent.com/pub/Attack/proj/A55.7_infile
This is an image file, in JPEG format, as specified here:

JPG Signature Format: Documentation & Recovery Example

Decrypt the file. When you get it, change its filename extension to JPG and open it in an image viewer or Web browser.

The flag is visible in the image.


Posted: 11-6-19
Quotes and flag numbers fixed 11-21-19
A55.4_infile uploaded 11-25-19