Tuesday, March 6, 2012

Vigenere Encryption / Giovan's Cipher


The Vigenère cipher was originally described by Giovan Battista Bellaso in his 1553 book La cifra del. Sig. Giovan Battista Bellaso.  Somehow it gained popularity and was misattributed and named after Blaise de Vigenère.  In appearance, it almost appears unbreakable.  It earned the title le chiffre inéchiffrable, French for 'the indecipherable cipher.'  Being such a well known and common cipher, it is anything but indecipherable.  It has a basis of a Caesar cipher meaning that it is a shift cipher, but it switches for each letter of the key, earning it the category of a polyalphabetic substitution cipher.  Much stronger than it's predecessor, but it's still not bulletproof.


Well, let's build a function to generate them.  The math behind encryption and decryption is really the same as a caesar cipher, except that your key depends on which character you are at.  In the function, we are storing each key value into our array named $aKey.  We do this for good programming practice and speed.


Let's review our formula for encryption.  It is almost the same formula.  We set it to handle up to 256 characters.  The only other change is that n is dynamic. n will be the ascii value of the character of the key we are on.  As we increase our loop, it goes back to the first character in the key. 





For decryption, we simply are inverting n.  We are going to do it programmatically, but this is how it works.





Not much different than what we did on the Caesar, just n is "rolling."   Let's take a look at the function I wrote.


// Usage:
// Encrypt: vigenere('Attack at dawn.', 'classified', true);
// Decrypt: vigenere('¤àÕÔÖÔ†ÊÙ„ÇÍØá¡', 'classified', false)
function vigenere($sInput = null, $sKey = null, $bEncrypt = true) {
$aKey = array();
$iLength = strlen($sKey)-1;
// We put our key values into an array to prevent having to calculate
// it every character.  It will increase speed, especially on longer messages
while ($iLength >= 0) {
$aKey[$iLength] = ($bEncrypt) ? ord($sKey[$iLength]) : 0 - ord($sKey[$iLength]);
$iLength--;
}
$iLength = strlen($sInput);
$iS = sizeof($aKey);
$sReturn = '';
// Pasre the message.  
for ($i = 0; $i < $iLength; $i++) {
// Our shift code is stored in $aKey[($i % $iS)]
// We add % 256 to limit it to the ASCII chart.
$sReturn .= chr((ord($sInput[$i])+$aKey[($i % $iS)]) % 256);
}
return $sReturn;
}


Look at that, you passed a hidden message saying "Attack at dawn."  I'd hate to be your enemy come morning.  Of course, I might not mind if I knew a bit about cryptanalysis.

Look for the next post in the series to contain hints on cracking the code.  We will talk about the Friedman test & Kasiski examination to determine the length of the key before we show how you crack the code without using brute force.

I look forward to questions and comments.

No comments:

Post a Comment