Cifrados: Vigenere

Cifrados: Vigenere

Continuando la serie de artículos sobre cifrados, el turno es para Vigenère un cifrado creado por Leone Battista Alberti que trabaja por sustitución, este algoritmo es muy parecido al Cesar y la diferencia es que tiene una semilla mucho más complicada de hallar ya que esta es una palabra la cual se itera también y se hace la suma de la siguiente manera:

(PosicionTxT + PosicionSeed) % alfabeto.longitud

Del concepto al código

Conociendo el funcionamiento básico de vigenere, pasemos a ver su implementación en diferentes lenguajes de programación:

Java

/*
Modulo Vigenere para RiCrypt

Cifrado por sustitucion usando sumas y restas modulares en el alfabeto
normal pero altercadas con una semilla como palabra.

Phicar
project-ric.org
phicar@yashira.org
*/
public class Vigenere{
public static String TxT,Seed;
public static String Charset = "abcdefghijklmnopqrstuvwxyz";
public Vigenere(String TxT,String Seed){
this.Seed = Desn(Seed);
this.TxT = TxT;
}
public static String Cifrar(){
String Cifrado = "",a=TxT.toLowerCase();
for(int n = 0,c=0;n<TxT.length();n++,c = (c+1)%Seed.length()){
if(Charset.indexOf(a.charAt(n))!=-1){
int tmp = (Charset.indexOf(a.charAt(n))+Charset.indexOf(Seed.charAt(c)))%Charset.length();
Cifrado+=(Charset.indexOf(TxT.charAt(n))!=-1)?Charset.charAt(tmp):String.valueOf(Charset.charAt(tmp)).toUpperCase();
}else{
c-=1;
Cifrado+=TxT.charAt(n);
}
}
return Cifrado;
}
public static String DesCifrar(){
String DesCifrado = "";
String a = TxT.toLowerCase();
for(int n = 0,c=0;n<a.length();n++,c=(c+1)%Seed.length()){
if(Charset.indexOf(a.charAt(n))!=-1){
int tmp = (Charset.indexOf(a.charAt(n))-Charset.indexOf(Seed.charAt(c)));
tmp = (tmp<0)?(tmp+Charset.length()):tmp;
DesCifrado+=(Charset.indexOf(TxT.charAt(n))!=-1)?Charset.charAt(tmp):String.valueOf(Charset.charAt(tmp)).toUpperCase();
}else{
c-=1;
DesCifrado+=TxT.charAt(n);
}
}
return DesCifrado;
}
public static String Desn(String a){
String b = "";
for(int n = 0;n<a.length();n++){
if((Charset.indexOf(a.charAt(n))!=-1)||(Charset.indexOf(String.valueOf(a.charAt(n)).toLowerCase())!=-1))
b+=a.charAt(n);
}
return b;
}
}

C++

    /************************************************
*  Nombre : Vigenere.cpp                        *
*                                               *
*  Cifrado de cesar de sustitución multiple     *
*  por medio de sumas y restas del alfabeto     *
*                                               *
*  Fulapol                                      *
*  Fulapol@gmail.com                            *
*  my.opera.com/fulapol                         *
*                                               *
************************************************/

#include <string>

Public Class Vigenere{
private:
string texto,semilla,letras;
letras = "abcdefghijklmnopqrstuvwxyz"
string limpiar(string cadena);
//Las variables son privadas, el metodo limpiar
//es privada ya que solo lo utilizan los otros
//metodos para limpiar la entrada

public:
vigenere(string orig, string sem);
string cifrar();
string descifrar();
//Esto es publico porque es la unica forma de
//accesar a los datos de la clase

}

/************************************************
*                                               *
*  El Constructor que debe recibir la cadena a  *
*  tratar y la cadena semilla                   *
*                                               *
************************************************/

vigenere::vigenere(string orig, string sem){
this->texto = limpiar(orig);
this->semilla = limpiar(sem);
}

/************************************************
*                                               *
*  El metodo cifrar, que regresa una cadena de  *
*  texto que solo despues de ser cifrada        *
*                                               *
************************************************/

vigenere::cifrar(){
string final;
int i,movimiento,rotacion,total;
size_t pos,pos2;
//Las variables serviran para registrar la posicion
//de las letras y calcular la semilla

for(i=0,rotacion=0;i<texto.length();i++,rotacion++){
pos = letras.find(texto.at(i));
pos2 = letras.find(semilla.at(rotacion));
total = ((int)(pos+pos2))%letras.length();
//El total que marca la posicion de la letra y la
//semilla sumadas

if(total > letras.legth())
movimiento = total-letras.length();
else
movimiento = total;
//Para asegurarnos que esta dentro del rango

final.apend(letras,movimiento,1)
if(rotacion==semilla.length())
rotacion=0;
//Si se acaba la semilla, regresar al principio

}
return final;
}

/************************************************
*                                               *
*  El metodo descifrar, que regresa una cadena  *
*  de texto que solo despues de ser descifrada  *
*                                               *
************************************************/

vigenere::descifrar(){
//La funcion es exactamente la misma que en el metodo
//cifrar, solo que aqui las posiciones se restan para
//eliminar la semilla del texto

string final;
int i,movimiento,rotacion,total;
size_t pos,pos2;
for(i=0,rotacion=0;i<texto.length();i++,rotacion++){
pos = letras.find(texto.at(i));
pos2 = letras.find(semilla.at(rotacion));
total = ((int)(pos-pos2))%letras.length();
if(total < 0)
movimiento = total+letras.length();
else
movimiento = total;
final.apend(letras,movimiento,1)
if(rotacion==semilla.length())
rotacion=0;
}
return final;
}

/************************************************
*                                               *
*  El metodo limpiar, que regresa una cadena de *
*  texto que solo contiene los caracteres       *
*  soportados por la clase                      *
*                                               *
************************************************/

vigenere::limpiar(string cadena){
int i;
string final;
for(i=0;i<cadena.length();i++){
if(cadena.at(i)>64 && cadena.at(i)<91)
cadena.at(i) += 32;
//Pasamos el caracter a minusculas

if(letras.find(cadena.at(i))!=-1)
final.apend(cadena.at(i))
//Agregamos a la cadena final el caracter
//si se encuentra en la variable letras

}
return final;
}

PHP

<?php
/******************************************************************************
* Nombre : Vigenere.php
* Clase para el cifrado de Vigenere para Project-RIC. Este es un cifrado de
* sustitución polialfabetico, siendo una variación del cifrado de cesar. La diferencia
* es que usa una palabra como semilla, la cual cada caracter representa el indice
* del charset a ser sumado en las operaciones modulares. Esta semilla se repita cuantas
* veces sea necesario hasta cifrar/descifrar toda la cadena.
* @copyLeft  : Project-RIC
* @package   : RiCrypt
* @author      : D-m-K, d4rk.m0nk3y@gmail.com, my.opera.com/d-m-k
******************************************************************************/
class Vigenere {
var $charset;
var $txt;
var $seed;

/*****************************************************************************
* Constructor
* Cifra la cadena pasada como parametro realizando la sustitucion
* de la cadena original la cantidad de veces definida en el parametro
* @param  $s = Cadena original
*                $seed = Cantidad de rotaciones a cada letra
******************************************************************************/
public function __construct($s, $seed) {
$this->charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";  //Definicion del charset
$this->txt    = strtoupper($s);
$this->seed   = strtoupper($seed);
}

/************************************************************************************
* Funcion :  encode
* Cifra la cadena pasada como parametro realizando una sustitucion
* polialfabetica a traves de sumas modulares dependiendo el indice de cada caracter de la semilla
* @param  $seed = Semilla con la que sera cifrado el mensaje
* @return $result = Mensaje cifrado
************************************************************************************/
function encode(){
$result = "";                                           //Cadena donde queda el resultado
$x = 0;                                                         //Indice de la semilla
$p = 0;                                                         //Posicion para relizar la operacion modular
for($i=0; $i<strlen($this->txt); $i++){
if(strstr($this->charset, $this->txt{$i})){//Evaluo si existe el caracter en el charset
$x = strpos($this->charset, $this->seed{($p % strlen($this->seed))});
$result .= $this->rotate($this->txt{$i}, $x);   //Invoco funcion que hace la rotacion
$p++; //Aumento el indice para la operacion modular
}else{//Si no existe dejo el caracter evaluado
$result .= $this->txt{$i};
continue;
}
}
return $result;                                         //Devuelvo la cadena Cifrada =)
}

/************************************************************************************
* Funcion  :  decode
* DesCifra la cadena pasada como parametro realizando una sustitucion
* polialfabetica a traves de sumas modulares dependiendo el indice de cada caracter de la semilla
* @param  $seed = Semilla con la que sera cifrado el mensaje
* @return $result = Mensaje cifrado
************************************************************************************/
function decode(){
$result = "";                                           //Cadena donde queda el resultado
$x = 0;                                                         //Indice de la semilla
$p = 0;                                                         //Posicion para relizar la operacion modular
for($i=0; $i<strlen($this->txt); $i++){
if(strstr($this->charset, $this->txt{$i})){//Evaluo si existe el caracter en el charset
$x = strpos($this->charset, $this->seed{($p % strlen($this->seed))});
$result .= $this->rotate($this->txt{$i}, -$x);  //Invoco funcion que hace la rotacion
$p++; //Aumento el indice para la operacion modular
}else{//Si no existe dejo el caracter evaluado
$result .= $this->txt{$i};
continue;
}
}
return $result;                                         //Devuelvo la cadena DesCifrada =)
}

/*****************************************************************************
* Funcion : rotate
* Realiza la rotacion de un caracter sobre el charset dependiendo el valor de la semilla
* de la cadena original la cantidad de veces definida en el parametro
* @param  $s = Cadena original
*                 $n = Cantidad de rotaciones
* @return  $result = Valor del nuevo caracter de acuerdo al indice
*****************************************************************************/
function rotate($c, $n){
$result = "";                   //Texto de salida
$tamC = strlen($this->charset); //Longitud de la cadena del charset
$k = 0;                                 //Indice para sustitucion de la cadena con el charset
$n %= $tamC;                    //Semilla ó rotacion
$c = strtoupper($c);    //Convierto a mayuscula el caracter
//Realizo la sustitución de cada caracter
//Evaluo si el caracter en la posicion $i existe, de lo contrario
//Dejo el caracter que esta por defecto
if(strstr($this->charset, $c)){
$k = (strpos($this->charset, $c) + $n);
if($k < 0){
$k += $tamC;
}else
$k %= $tamC;
$result .= $this->charset{$k};
}else{
$result .= $c;
}
return $result;
}
}
?>
<?php
include 'Vigenere.php';                                 //Incluyo la clase
$mensaje   = $_POST['mensaje'];                 //Mensaje a cifrar
$semilla   = $_POST['semilla'];                 //Semilla o palabra con la que se cifrara/descifrara el mensaje
$tarea     = $_POST['tarea'];                   //Boton pulsado por el usuario
$salida    = "";                                                //Variable que guarda el mensaje
//Aqui esta la magia
if($_POST && $mensaje != "" && $semilla != ""){
//CIFRADO DEL MENSAJE
if($_POST['tarea'] == "Cifrar"){
$cipher    = new Vigenere($mensaje, $semilla);
$salida = $cipher->encode();
}
//DESCIFRADO DEL MENSAJE
if($_POST['tarea'] == "DesCifrar"){
$cipher    = new Vigenere($mensaje, $semilla);
$salida = $cipher->decode();
}
}
?>
<html>
<head>
<title> .:: Implementacion de la cifra de vigenere ::. </title>
</head>
<body>
<h1>Vigenere</h1><hr>
<!-- Datos para el cifrado -->
<form method="post">
<strong>Mensaje a cifrar / descifrar :</strong> <br>
<textarea name="mensaje" style="width:500px;border:1px solid #555"><?php echo $_POST['mensaje']; ?></textarea><br>
<strong>Semilla :</strong>
<input type="text" name="semilla" style="width:150px;border:1px solid #555" value="<?php echo $_POST['semilla']; ?>"> |
<input type="submit" name="tarea" value="Cifrar"> |
<input type="submit" name="tarea" value="DesCifrar">
</form>
<?php
//Muestro el mensaje de salida
if($salida != ""){
echo "<strong> Resultado del criptograma </strong> <br> \n";
echo "<div class='mensaje'>" . $salida . "</div>";
}
?>
</body>
</html>
Por Phicar

Artículos Relacionados

Cifrados: RSA

Cifrados: RSA

¿Qué es y cómo funciona un ataque por fuerza bruta?

2 Comentarios

  1. David - julio 25, 2012, 11:24 am Responder

    Buenos días, gracias por su ayuda, tengo una duda, cuando monto el código en DevC++, me aparece un error en la primera linea, donde dice public class vigenere{ , si me podrías ayudar, gracias 🙂

  2. enRIq - octubre 26, 2014, 11:43 am Responder

    Me marca el mismo error que comentar de la primer linea

Deja un comentario

Tu email no será publicado.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*