# Relative security of a Vigenère cipher

Within a closed computer network, I am ciphering some plaintext data as an added security measure. This is below several other layers of protection. For various technical reasons, I am restricted to plain-text, UTF-8 data. To that end, I have been using a Vigenère cipher with pre-shared key database. The keys range from 30 to 100 characters, and are not dictionary words.

My question is regarding the Vigenère cipher: It is my understanding that the security of this cipher is directly related to the length and security of the keys. Long and tightly secured keys bring this cipher on par with many more complex techniques. Is that true, or is this a "kiddie" cipher that could be cracked while you sleep?

Edit It may bear mentioning, the text that is being ciphered is JSON encoded data arrays, which is human readable but not "natural language" -- it contains many symbols interspersed with the actual data.

EDIT 2 Plaintext length varies unpredictably, from 100 characters to 5,000 plus. The data is being transported via SSL, so this is, as I mentioned, intended as yet another added layer, not the whole and sum of security used.

-

You say "the keys range from 30 to 100 characters and are not dictionary words." How are the keys derived? Randomly? How long are the plaintexts? – mikeazo♦ Aug 1 '12 at 12:03
Plaintext is wildly varied in length, the keys were derived by gluing fragments of random long dictionary words together with fragments of random characters – Chris Aug 1 '12 at 14:23

## 3 Answers

The real security of Vigenere is difficult to quantify. A million character plaintext with a 10 character password is easy to break. But a 10 character plaintext with a 10 character randomly chosen password is essentially a one-time-pad and theoretically unbreakable.

Given the data you've told us (plaintext: 100 to 5000 characters; password: 30 to 100 characters), it would seem that Vigenere adds very little. A 5000 character plaintext with 30 character password yields $5000/30\approx 167$ characters per plaintext alphabet. That is easily breakable using statistical methods. Other configurations given the numbers you've specified might be slightly harder (especially if the password were completely random).

That said, if you are already using SSL and adding Vigenere "as yet another added layer" of security, the increase in security by using Vigenere is 0 at worst and negligible at best. An attacker who can break SSL will have no problems breaking Vigenere.

-

Thanks! The phrase "An attacker who can break SSL will have no problems breaking Vigenere." really settles it for me -- you're absolutely right about that. – Chris Aug 1 '12 at 17:56

The Vigenère cipher has many weaknesses, but perhaps the most obvious ones are:

• An attacker, who knows (or can guess) as many consecutive characters of any plaintext message as there are in the key, can trivially recover the key and thus decrypt all messages. (In fact, the characters need not even be consecutive, they just need to cover the entire key, or at least most of it.)

• For most natural messages, it's fairly easy to guess the key length, for example by looking at correlations between characters $n$ positions apart.

• An attacker who knows (or can guess) the key length can divide the ciphertext into blocks of this length and decrypt one block with the other as the key to obtain a linear combination of the two messages. This will often have enough structure to allow the original blocks to be (at least partially) reconstructed, which in turn allows recovery of the key. (Also, if there are multiple messages encrypted with the same key, or if the key itself is not completely random, other similar attacks may be possible even without guessing the key length.)

In short, I would strongly recommend not using the Vigenère cipher for any purpose, except perhaps for puzzles that are meant to be broken. At the very least, use a stream cipher like RC4, which is simple enough to implement off the top of your head. Also, if you need to encrypt multiple files, include a unique initialization vector with each (or derive one from some unique value, like the name of the file) and hash it together with your master key.

(Using a stream cipher in such a way that they output remains valid Unicode text is a somewhat non-trivial exercise in format-preserving encryption, but it should be no harder than doing the same with a Vigenère cipher. Personally, I'd suggest encrypting the input as a binary octet stream and then Base64-encoding it into printable ASCII as the simplest secure method.)

-

Thanks for the info! It was hard to decide which answer to accept, since they basically all say "don't!" (with varying degrees of exclamation). I went with @mikeazo's answer because I appreciate that phrase "An attacker who can break SSL will have no problems breaking Vigenere.", and I guess that is the bottom line. Thanks again, +1 – Chris Aug 1 '12 at 17:55
With sufficient ciphertext, statistical analysis can also reveal the key length. Further analysis on each block can potentially reveal each letter in the key regardless of whether or not they are random. – Stephen Harris Aug 9 '12 at 10:38

Eek! The Vigenere cipher is completely and totally insecure. You should never use it. Instead, use a modern authenticated encryption scheme.

If you are protecting data in transit, I recommend using TLS (or SSL). If you are protecting data in storage, I recommend encrypting it with GPG (or PGP). This is the simplest, easiest way to get well-vetted cryptography that is unlikely to have a catastrophic flaw.

-
{"extraction_info": {"found_math": true, "script_math_tex": 0, "script_math_asciimath": 0, "math_annotations": 0, "math_alttext": 0, "mathml": 0, "mathjax_tag": 0, "mathjax_inline_tex": 2, "mathjax_display_tex": 0, "mathjax_asciimath": 0, "img_math": 0, "codecogs_latex": 0, "wp_latex": 0, "mimetex.cgi": 0, "/images/math/codecogs": 0, "mathtex.cgi": 0}, "config": {"markdown_headings": true, "markdown_code": true, "boilerplate_config": {"ratio_threshold": 0.3, "absolute_threshold": 10, "end_threshold": 15, "enable": true}, "remove_buttons": true, "remove_image_figures": true, "remove_link_clusters": true, "table_config": {"min_rows": 2, "min_cols": 3, "format": "github"}, "remove_chinese": true, "remove_edit_buttons": true, "extract_latex": true}, "english_confidence": 0.9413529634475708, "perplexity_flag": "middle"}