Difference between revisions of "Vernam Cipher"
(→Revision Questions) |
|||
Line 6: | Line 6: | ||
==Example== | ==Example== | ||
+ | <syntaxhighlight lang="csharp" line> | ||
+ | using System; | ||
+ | using System.Collections.Generic; | ||
+ | using System.Linq; | ||
+ | using System.Text; | ||
+ | using System.Threading.Tasks; | ||
+ | using System.IO; | ||
+ | |||
+ | namespace VernamCipher | ||
+ | { | ||
+ | class Program | ||
+ | { | ||
+ | private static readonly Random getrandom = new Random(); | ||
+ | private static readonly object syncLock = new object(); | ||
+ | public static int GetRandomNumber(int min, int max) | ||
+ | { | ||
+ | lock (syncLock) | ||
+ | { // synchronize | ||
+ | return getrandom.Next(min, max); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | static void Main(string[] args) | ||
+ | { | ||
+ | string ciphertext = ""; | ||
+ | string plaintext = ""; | ||
+ | char cipherchar; | ||
+ | int cipherascii; | ||
+ | //string key = "the quick brown fox jumped over the lazy dog"; | ||
+ | |||
+ | string key = ""; | ||
+ | |||
+ | Console.WriteLine("Please enter a message and press enter to encrypt it:"); | ||
+ | plaintext = Console.ReadLine(); | ||
+ | |||
+ | //add option to change the key | ||
+ | |||
+ | using (System.IO.StreamWriter file = | ||
+ | new System.IO.StreamWriter(@"me.cipherkey")) | ||
+ | { | ||
+ | for (int i = 0; i < plaintext.Length + 1; i++) | ||
+ | { | ||
+ | key += (char)GetRandomNumber(0, 255); | ||
+ | } | ||
+ | file.Write(key); | ||
+ | } | ||
+ | |||
+ | //check the size of the key (it should be the same size or bigger than the plaintext | ||
+ | Console.WriteLine("Your plain text was:"); | ||
+ | Console.WriteLine(plaintext); | ||
+ | |||
+ | int[] asciiValues = new int[plaintext.Length]; | ||
+ | |||
+ | using (System.IO.StreamWriter file = | ||
+ | new System.IO.StreamWriter(@"me.cipher")) | ||
+ | { | ||
+ | for (int charpos = 0; charpos < plaintext.Length; charpos++) | ||
+ | { | ||
+ | cipherascii = plaintext[charpos] ^ key[charpos]; // ^ is the xor character in C# | ||
+ | cipherchar = (char)cipherascii; // this is casting, it changes cipherascii to a char for this line only | ||
+ | asciiValues[charpos] = cipherascii; | ||
+ | ciphertext = ciphertext + cipherchar; | ||
+ | Console.WriteLine("plain: " + plaintext[charpos]); | ||
+ | Console.WriteLine("key: " + key[charpos]); | ||
+ | Console.WriteLine("cipher: " + cipherascii); | ||
+ | |||
+ | file.Write((char)cipherascii); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | Console.WriteLine("Your cipher text is:"); | ||
+ | Console.WriteLine(ciphertext); | ||
+ | Console.WriteLine("Or as ascii values:"); | ||
+ | for (int value = 0; value < ciphertext.Length;value++) | ||
+ | { | ||
+ | Console.WriteLine(asciiValues[value]); | ||
+ | } | ||
+ | |||
+ | string text = System.IO.File.ReadAllText(@"me.cipher"); | ||
+ | |||
+ | string newStr = ""; | ||
+ | for (int charpos = 0; charpos < plaintext.Length; charpos++) | ||
+ | { | ||
+ | cipherascii = text[charpos] ^ key[charpos]; // ^ is the xor character in C# | ||
+ | cipherchar = (char)cipherascii; // this is casting, it changes cipherascii to a char for this line only | ||
+ | asciiValues[charpos] = cipherascii; | ||
+ | newStr = newStr + cipherchar; | ||
+ | } | ||
+ | |||
+ | Console.WriteLine(newStr); | ||
+ | |||
+ | //add the code to decrypt | ||
+ | |||
+ | Console.ReadLine(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
==Perfect Security== | ==Perfect Security== |
Revision as of 13:50, 15 November 2017
The Vernam Cipher uses an encryption key (or One Time Pad) which must be equal or longer in characters than the plaintext. It should be random and be used only once. The plaintext and the key are combined to produce the cipher text. The message can then be decrypted with the key and the cipher text.
Both parties would need to meet up to exchange the key, however you can imagine using a random book and starting the message with a page and line number. The Vernam Cipher uses ASCII binary values and the XOR logic gate. If you have 2 inputs (A & B) then the XOR will produce an output only when A or B have an input BUT NOT BOTH.
Example
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using System.IO;
7
8 namespace VernamCipher
9 {
10 class Program
11 {
12 private static readonly Random getrandom = new Random();
13 private static readonly object syncLock = new object();
14 public static int GetRandomNumber(int min, int max)
15 {
16 lock (syncLock)
17 { // synchronize
18 return getrandom.Next(min, max);
19 }
20 }
21
22 static void Main(string[] args)
23 {
24 string ciphertext = "";
25 string plaintext = "";
26 char cipherchar;
27 int cipherascii;
28 //string key = "the quick brown fox jumped over the lazy dog";
29
30 string key = "";
31
32 Console.WriteLine("Please enter a message and press enter to encrypt it:");
33 plaintext = Console.ReadLine();
34
35 //add option to change the key
36
37 using (System.IO.StreamWriter file =
38 new System.IO.StreamWriter(@"me.cipherkey"))
39 {
40 for (int i = 0; i < plaintext.Length + 1; i++)
41 {
42 key += (char)GetRandomNumber(0, 255);
43 }
44 file.Write(key);
45 }
46
47 //check the size of the key (it should be the same size or bigger than the plaintext
48 Console.WriteLine("Your plain text was:");
49 Console.WriteLine(plaintext);
50
51 int[] asciiValues = new int[plaintext.Length];
52
53 using (System.IO.StreamWriter file =
54 new System.IO.StreamWriter(@"me.cipher"))
55 {
56 for (int charpos = 0; charpos < plaintext.Length; charpos++)
57 {
58 cipherascii = plaintext[charpos] ^ key[charpos]; // ^ is the xor character in C#
59 cipherchar = (char)cipherascii; // this is casting, it changes cipherascii to a char for this line only
60 asciiValues[charpos] = cipherascii;
61 ciphertext = ciphertext + cipherchar;
62 Console.WriteLine("plain: " + plaintext[charpos]);
63 Console.WriteLine("key: " + key[charpos]);
64 Console.WriteLine("cipher: " + cipherascii);
65
66 file.Write((char)cipherascii);
67 }
68 }
69
70 Console.WriteLine("Your cipher text is:");
71 Console.WriteLine(ciphertext);
72 Console.WriteLine("Or as ascii values:");
73 for (int value = 0; value < ciphertext.Length;value++)
74 {
75 Console.WriteLine(asciiValues[value]);
76 }
77
78 string text = System.IO.File.ReadAllText(@"me.cipher");
79
80 string newStr = "";
81 for (int charpos = 0; charpos < plaintext.Length; charpos++)
82 {
83 cipherascii = text[charpos] ^ key[charpos]; // ^ is the xor character in C#
84 cipherchar = (char)cipherascii; // this is casting, it changes cipherascii to a char for this line only
85 asciiValues[charpos] = cipherascii;
86 newStr = newStr + cipherchar;
87 }
88
89 Console.WriteLine(newStr);
90
91 //add the code to decrypt
92
93 Console.ReadLine();
94 }
95 }
96 }
Perfect Security
The Vernam Cipher is described as having perfect security. This means an eavesdropper would not, by gaining knowledge of the ciphertext but not of the key, be able to improve their guess of the plaintext even given unlimited computing power. Cryptanalysis will not produce any meaningful results because the distribution of any frequency analysis will be evenly distributed. This assumes that the key:
- Must be truly random
- Must be as long as the plaintext
- Must never be reused in whole or part
- Must be kept secret
Computational Security
An encryption method is considered to be computationally secure if it is safe to assume that no known attack can break it in a practical amount of time. This relaxes perfect security by allowing security to fail with tiny probability, and by only considering efficient attacks. Apart from the Vernam Cipher every encryption method could be brute forced eventually given unlimited processing power and time.
If a super computer can check one key per clock cycle it could check 280 keys in one year. This is 1,208,925,819,614,629,174,706,176 different keys. However the number of keys it could check in the whole time from the big bang until now (14 billion years) would be 2112. Therefore keys which have 128 bits (2128) should be computationally secure.
Even RSA encryption could be broken with unlimited time & processing power. It uses the product of 2 large prime numbers (atleast 512 digits) in its algorithm. This is easily calculated, however identifying which 2 numbers have been used for a given product is much harder than it sounds. The 2 prime numbers cannot be close together . In 2009, computer scientists using factorisation were able to discover the primes within a 768-bit number, but it took almost two years and hundreds of computers to factor it. If it was on a single machine they estimate it would have taken 1500 years, the scientists also estimated that it would take 1,000 times longer to break a 1,024-bit encryption key, which was originally used for online transactions. Now we use 2048 or 4096 bits for online transactions.