Sunday, October 4, 2015

Breaking Caesar Cipher by brute force

I started learning about cryptography. Given a data we do some transformation or certain steps on the data such that data looses or hides its original form. Any person who sees that new form does not recognizes whats its original form. This is encryption. Again we can use certain steps on new form of data to get back the original form of data. This is decryption. 

PlainText --> Encryption Engine -> Cryptic Text

Cryptic Text --> Decryption Engine -> Plain Text.

Ciphers are nothing but those encryption engines which will generate the cryptic message given a plain message. There are different types of ciphers. I will be explaining one of the oldest ciphers. Caesar Cipher. Yes as name suggests it was used by Julius Caesar. This is a simple cipher. Given a plain text, each character in that message will be replaced by another symbol. There is a concept of key. Key place a very important role is conversion of text to cryptic text as well as reversing the cryptic text to plain text. So key will be present with the person who is preparing the cryptic text. And also the same key will be present with the person to whom the message needs to b passed.
English alphabet has totally 26 characters. Now in Caesar cipher, these English alphabet will be replaced again by English alphabet. Example if character is 'b' and key is 3 then b will be replaced by 'e'.  Suppose character is 'z' then it will be replaced by 'c'. So number of possible keys are 25 i.e. number of English alphabet -1. Basically it means I can replace a character x with 25 other characters.

for (int i = 0; i < nSize; i++)
{
if (strPlainText[i] >= 65 && strPlainText[i] <= 90)
{
//Capital letters
nTemp = strPlainText[i] + *pKey;

if (nTemp > 90)
{
nTemp = nTemp - 26;
}
strCipherText[i] = nTemp;
}
else if (strPlainText[i] >= 97 && strPlainText[i] <= 122)
{
//small letters
nTemp = strPlainText[i] + *pKey;

if (nTemp > 122)
{
nTemp = nTemp - 26;
}
strCipherText[i] = nTemp;
}
else
{
strCipherText[i] = strPlainText[i];
}
}

In simple words this is doing ch = (pt + k)mod 26. where pt is the character from plain text, k is the key and ch is character from cipher text. In code I am trying to first check whether character obtained is a small letter alphabet or capital letter aplhabet. If not then it is a numeric or some other symbols. Those characters are not touched. If it is a smaller letter than it will be replaced by cipher text of smaller letter. If it is a capital letter I am replacing the with cipher text of capital letter. 

Deciphering is a simple step. pt = (ch - k)mod26. ch is the character from cipher text, k is the key and pt is the character from plain text. 

for (int i = 0; i < nSize; i++)
{
if (strCipherText[i] >= 65 && strCipherText[i] <= 90)
{
nTemp = strCipherText[i] - nKey;
if (nTemp < 65)
{
nTemp = 26 + nTemp;
}
strPlainText[i] = nTemp;
}
else if (strCipherText[i] >= 97 && strCipherText[i] <= 122)
{
nTemp = strCipherText[i] - nKey;
if (nTemp < 97)
{
nTemp = 26 + nTemp;
}
strPlainText[i] = nTemp;
}
else
{
strPlainText[i] = strCipherText[i];
}
}

Breaking the cipher - Now if I have the text but I don't have the key. In this case I know that possible keys are from 1-25. Try all these on the cipher text. They check the answer which makes the correct sense of the text. 

for (int i = 1; i < 25; i++)
{
memset(strKey, '\0', 5);
sprintf_s(strKey, "\n%d\n", i);
fwrite(strKey, sizeof(char), strnlen_s(strKey,6), fpOutputFile);
for (int j = 0; j < nSize; j++)
{
if (strCipheredText[j] >= 65 && strCipheredText[j] <= 90)
{
nTemp = strCipheredText[j] - i;
if (nTemp < 65)
{
nTemp = 26 + nTemp;
}
strPlainText[j] = nTemp;
}
else if (strCipheredText[j] >= 97 && strCipheredText[j] <= 122 )
{
nTemp = strCipheredText[j] - i;
if (nTemp < 97)
{
nTemp = 26 + nTemp;
}
strPlainText[j] = nTemp;

}
else
{
strPlainText[j] = strCipheredText[j];
}
}
fwrite(strPlainText, sizeof(char), strnlen_s(strPlainText, nSize), fpOutputFile);
memset(strPlainText, '\0', nSize+1);
}

As you can see, I am trying all the 25 keys and storing the result in a file. 

If plain text was "Harsha Kadekar" and key was 13 then cryptic text was "Unefun Xnqrxne"


And I am learning from book -> Cryptography and Network Security: Principles and practices by William Stallings.