How to implement a Symmetric Key Cipher

Started by
11 comments, last by Mantear 13 years, 4 months ago
Reading that page, I see the potential vulnerability described, but it doesn't seem likely.

You'd have to use a fairly short key and have a LOT of instances of words being repeated very often (at least as many times as the length of the key) to have an even chance of creating a repeated string that can lead to decryption.

I guess you could say that as the ratio of (message length) to (key length) grows, the chance of this vulnerability occurring increases.

And I imagine I could solve this problem completely by using a Merssene twister as the key. Or something like:

md5(first 32 bits of md5(small memorable key)).md5(second 32 bits of md5(small memorable key)).md5(third 32 bits of md5(small memorable key)).md5(last 32 bits of md5(small memorable key))

Which just turns a small memorable password into a 512 bit monstrosity.
Advertisement
yes, but you don't need repeats as i mentioned to posts above. you can break the key into pieces because of they way the xor is applied.
Imagine I manage to make you encrypt a file that only contains a long list of zero bytes. The encoding would be the key repeating for the length of the file.

Now imagine I simply happen to know a file that you are encrypting with this method. I can now XOR the original file with the encrypted file and again I will get the key repeating for the length of the file.

If you are encoding a C++ file, I can make a guess that the first few characters will be "#include <" or "#include<". By XORing this string with the beginning of the encrypted file, I will find the first 80 bits of the key. I can now try to guess the length of the key by XORing with the part I know at different parts of the file and seeing which get converted to apparently reasonable C++ code. Then guessing the characters before and after some of the windows that I have already decoded wouldn't be too hard, and that would give me more bits of the key.

As you see, it's not too hard to make an attack of this type.

It might be fun for you to encode some longish C++ code with this method and let us have a go at attacking it.
If you really want to stick with XOR encryption instead of a "real" cipher, you should make it something like this:

for(...)
out = in ^ f(key, out[i-1])

where f(key, x) returns some value that depends on key and x in some non-obvious, non-linear way. Shifts paired with adds, multiplications modulo 16 bits, etc.

And you would absolutely need to add a random initialisation vector to every message.

Though if you need a symmetric cipher, I don't see why you can't just use something like for example TEA. Even the old, non-revised version is better than what 90% of all coders will come up with if they try to make something on their own.
If you want it safer, add 10 or 20 more rounds. If you don't care so much, but want it as fast as possible, reduce it to 4 or 8 rounds, it will still be better than XOR.

Or, just use AES, which is hardware-accelerated on the most recent CPUs and not too slow in software either.
I second the AES recommendation. The specification can be foud here:
csrc.nist.gov/publications/fips/fips197/fips-197.pdf

It explains how to implement it in great detail and even provides test vectors with expected output to verify your implementation. It even has intermediate step outputs to help debug. Works with 128-bit, 192-bit, or 256-bit keys.

The toughest part will be coming up with a key that you don't write down/store somewhere in plain text. Perhaps make a second application that takes an input text phrase and generates a key from that.

This topic is closed to new replies.

Advertisement