XOR Encryption using Go
I’ve previously written about the use of XOR encryption and the various benefits to this method of encryption for non-critical data encryption, but to summarize:
- Language and architecture independence
- The result is always reproducible under any conditions
- Easy to reverse the encryption
For more on the benefits of XOR, as well as the downsides, and when to use it, see my original post.
I like to add languages to my XOREncryption repository from time to time because I find I use XOR encryption frequently in various applications for semi-sensitive data, such as video game save state. Writing a XOR encryption method in a new language is pretty trivial, but it also requires a lot more understanding of the language than a “Hello World” program does, so it’s a fun little challenge to pop open Vi and try to write it out without referencing documentation or using Google.
The reason I’m writing today is I’ve added Go as one of the supported languages in my XOREncryption repository, and I’d like to show just how easy it is to use. Here’s a look at the code, which as you can see contains more whitespace and comments than actual logic. Again, XOR encryption is pretty trivial:
package xor // EncryptDecrypt runs a XOR encryption on the input string, encrypting it if it hasn't already been, // and decrypting it if it has, using the key provided. func EncryptDecrypt(input, key string) (output string) { for i := 0; i < len(input); i++ { output += string(input[i] ^ key[i % len(key)]) } return output }
We take in the string to encrypt (or decrypt) and a key to use for encryption. After that, we iterate over the input string, and add a single character to the output string, per iteration. This single character is the result of XOR-ing the current input index, and a character in the key. We use a modulus on the index and length of the key to iterate over the key, using a new character per iteration, and then resetting and starting at the beginning of the key once we’ve hit the end.
After importing the “xor” package, usage is very simple:
import "xor" func main() { key := "KCQ" data := "kylewbanks.com" encrypted := xor.EncryptDecrypt(data) fmt.Println("Encrypted:", encrypted) decrypted := xor.EncryptDecrypt(encrypted) fmt.Println("Decrypted:", decrypted) }
The key is essentially your password - it can be any length, but its the key to your data so you want to keep it secure. We pass the key and data to the EncryptDecrypt function, which will return a XOR-ed version of the data using the key - this is our encrypted result.
By passing the encrypted value back into the EncryptDecrypt function, using the same key, we will get a XOR-ed version of the encrypted string - this is our decrypted string, and will match the original data variable.
Here’s a look at the output:
Encrypted: :=.43*-:8m2$. Decrypted: kylewbanks.com
As you can see, the encrypted text is unrecognizable - it looks like gibberish. The decrypted text, however, is an exact match to our original data.
And that’s it - simple XOR encryption in Go! This implementation is completely compatible with all the other implementations in my XOREncryption repository, meaning you could encrypt a string in Python, and decrypt it in Go, for example, as long as you always provide the same key.