Fabio Donatantonio

Il cifrario di Vigenère in PHP  

realizzato da , il 21 ott. 2010, categoria PHP

PHP

In due articoli precedenti abbiamo analizzato, grazie a PHP, due algoritmi di cifratura: Cesare e Blowfish.
Il primo al solo scopo didattico-storico, mentre il secondo pienamente utilizzabile all’interno delle nostre applicazioni, viste le sue potenzialità e il grado di sicurezza che fornisce.

Il cifrario di Vigenère è il più semplice dei cifrari polialfabetici. Si basa sull’uso di un versetto (chiave) per controllare l’alternanza degli alfabeti di sostituzione.
Il metodo si può considerare una generalizzazione del cifrario di Cesare; invece di spostare sempre dello stesso numero di posti la lettera da cifrare, questa viene spostata di un numero di posti variabile ma ripetuto, determinato in base ad una parola chiave e da scrivere ripetutamente sotto il messaggio, carattere per carattere:

testo in chiaro: CIAO MAMMA CIAO
chiave: CHIA VECHI AVEC
testo cifrato: EPIO HEOTI CDEQ

Il testo cifrato si ottiene spostando la lettera chiara di un numero fisso di caratteri, pari al numero ordinale della lettera corrispondente della chiave.
Per semplificare la cifratura/decifratura Vigenère propose una matrice quadrata (26 X 26) composta da alfabeti ordinati e spostati.
Nel codice che andremo a sviluppare utilizzeremo questa versione “classica” dell’algoritmo, difatti realizzeremo la matrice e la cifratura/decifratura verrà eseguita su di essa.
In fondo all’articolo è possibile provare e scaricare il codice completo.

Passiamo quindi al codice della classe che chiameremo vigenere.php.
La classe si comporrà dei seguenti metodi:

  • Costruttore per la realizzazione della matrice (tavola di Vigenère)
  • Metodo di cifratura
  • Metodo di decifratura
  • Metodo che stampa a video la tavola di Vigenère

Ecco il codice PHP:

<?php
class Vigenere{
	var $alfabeto = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N', 'O','P','Q','R','S','T','U','V','W','X','Y','Z');
	var $matrice;
	var $chiave;

	// Il costruttore imposta la chiave e realizza la matrice
	function Vigenere($chiave){
		$this->chiave = str_replace(array(" ",".",",",";"),"", $chiave);
		$app1 = array();
		$app2 = array();
		$alfabeto_app = array();
		for($i=0; $i<26; $i++){
			$k=0;
			$app1 = array_slice($this->alfabeto,0,$i);
			$app2 = array_slice($this->alfabeto,$i);
			$this->matrice[$i] = array_merge($app2,$app1);
		}
	}

	// Metodo che stampa la matrice
	function stampaTavola(){
		echo "<table border='1' cellpadding='1' cellspacing='0'>
		<tr><td rowspan='27' width='50px' align='center'>T<br>E<br>S<br>T<br>O<br> <br>I<br>N<br> <br>C<br>H<br>I<br>A<br>R<br>O<br></td><td colspan='26' align='center' height='50px'>CHIAVE</td></tr>";
		for($i=0; $i<26; $i++){
			echo "<tr>";
			for($j=0; $j<26; $j++){
				echo "<td align='center'>".$this->matrice[$i][$j]."</td>";
			}
			echo "</tr>";
		}
		echo "</table>";
	}

	// Metodo per la cifratura
	function cifratura($testo){
		$txt_cifrato = "";
		$l_chiave = strlen($this->chiave);
		$k = 0;
		for($i=0; $i<strlen($testo); $i++){
			$chr_t = substr($testo,$i,1);
			$chr_c = substr($this->chiave,$k,1);

			if(in_array(strtoupper($chr_t),$this->alfabeto) && in_array(strtoupper($chr_c),$this->alfabeto)){
				$x = array_search(strtoupper($chr_t),$this->alfabeto);
				$y = array_search(strtoupper($chr_c),$this->alfabeto);
				$txt_cifrato = $txt_cifrato.$this->matrice[$x][$y];
				$k++;
			}else{
				$txt_cifrato = $txt_cifrato.strtoupper($chr_t);
			}
			if($k==$l_chiave) $k = 0;
		}
		return $txt_cifrato;
	}

	// Metodo per la decifratura
	function decifratura($testo){
		$txt_decifrato = "";
		$l_chiave = strlen($this->chiave);
		$k = 0;
		for($i=0; $i<strlen($testo); $i++){
			$chr_t = substr($testo,$i,1);
			$chr_c = substr($this->chiave,$k,1);
			if(in_array(strtoupper($chr_t),$this->alfabeto) && in_array(strtoupper($chr_c),$this->alfabeto)){
				$colonna = array_search(strtoupper($chr_c),$this->alfabeto);
				$riga = 0;
				for($c=0; $c<26; $c++){
					if($this->matrice[$c][$colonna]==$chr_t){
						$riga = $c;
						break;
					}
				}
				$txt_decifrato = $txt_decifrato.$this->matrice[$riga][0];
				$k++;
			}else{
				$txt_decifrato = $txt_decifrato.$chr_t;
			}
			if($k==$l_chiave) $k = 0;
		}
		return $txt_decifrato;
	}
}
?>

Utilizzando un array contenete l’alfabeto, realizzeremo la matrice semplicemente tagliando ad ogni riga l’alfabeto in due parti, grazie alla funzione array_slice, per poi ricomporlo in maniera inversa.
Grazie a questa matrice i metodi cifratura e decifratura risultano abbastanza semplici:
- cicliamo lettera per lettera sul testo in chiaro e sulla chiave
- per ogni coppia di lettere (chiaro-chiave) verifichiamo le posizioni nell’alfabeto
- le coordinate x e y ottenute individueranno la lettera cifrata nella matrice
Il cuore del codice di cifratura è composto essenzialmente dalle tre righe:

$x = array_search(strtoupper($chr_t),$this->alfabeto);
$y = array_search(strtoupper($chr_c),$this->alfabeto);
$txt_cifrato = $txt_cifrato.$this->matrice[$x][$y];

Per la decifratura il procedimento è lo stesso, richiede solo una ricerca differente basata sulle colonne identificate dalle lettere che compongono la chiave.
Infine è presente un metodo denominato stampaTavola che visualizza a video la matrice favorendo la verifica manuale del processo di cifratura/decifratura.

La classe va così richiamata:

<?php
require_once 'vigenere.php';

$vigenere = new Vigenere($chiave);
$vigenere->stampaTavola();
$txt_cifrato = $vigenere->cifratura($testo);
$txt_decifrato = $vigenere->decifratura($txt_cifrato);
?>

All’interno della cartella contenente il codice completo sono presenti i seguenti file:

  • vigenere.php (la classe vista sopra)
  • test.php (lo script che effettua la cifratura/decifratura)
  • index.html (un form per il test di coppie chiave-testo in chiaro)

Cliccando qui è possibile vedere in azione il codice.

Cliccando qui è possibile scaricare il codice.

Leggi gli articoli correlati:

  1. Il cifrario di Cesare in PHP
  2. Il disco cifrante di Alberti in PHP
  3. Crittografia con Php/Blowfish

Invia questo articolo Invia ad un amico (Send this to a friend)
 Stampa questo articolo (Print now)  Stampa questo articolo (Print now)
:, , ,
Ti � piaciuto? Ti è piaciuto quest'articolo, guida o riflessione? Scoprine tanti altri nel menu articoli.

Torna sopra ↑

Spazio Pubblicitario

1 Trackback or Pingback for this entry

Commenta l'articolo - Ti risponderò in privato

Compila il modulo anti-spam sottostante

 

Fabio Donatantonio - Salerno - Città di Castello (PG) - fabio@donatantonio.net
Torna sopra ↑