Cifrado de Vigenère

El cifrado de Vigenère es un cifrado basado en diferentes series de caracteres o letras del cifrado César formando estos caracteres una tabla, llamada tabla de Vigenère, que se usa como clave. El cifrado de Vigenère es un cifrado por sustitución simple polialfabético.

Cuadro de Vigènere con las 27 letras del español

El cifrado de Vigenère se ha reinventado muchas veces. El método original fue descrito por Giovan Battista Belasso en su libro de 1553 La cifra del Sig. Giovan Battista Belasso. Sin embargo, fue incorrectamente atribuido más tarde a Blaise de Vigenère, concretamente en el siglo XIX, y por ello aún se le conoce como el "cifrado de Vigenère".

Este cifrado es conocido porque es fácil de entender e implementar, además parece irresoluble; esto le hizo valedor del apodo el código indescifrable (le chiffre indéchiffrable, en francés).

Historia

El primer cifrado polialfabético fue el llamado cifrado de Alberti, creado por Leon Battista Alberti hacia 1467. Para facilitar los cálculos se aprovechaba de un disco de metal que permitía cambiar fácilmente entre los diferentes alfabetos disponibles. El sistema de Alberti solo cambiaba entre alfabetos después de muchas palabras, y los cambios se indicaban escribiendo la letra del correspondiente alfabeto en el mensaje cifrado. Más tarde, en 1508, Johannes Trithemius, en su trabajo Poligraphia, inventó la tabula recta, que es básicamente la tabla de Vigenère. Trithemius, sin embargo, solo proporcionó un sistema de cambio progresivo, rígido y predecible entre alfabetos.

Lo que ahora se le conoce como el cifrado de Vigenère, fue originalmente descrito por Giovan Battista Belasso en su mencionado libro de 1533, quien construyó el cifrado basándose en la tabula recta de Trithemius, pero añadió una clave repetida para cambiar cada carácter entre los diferentes alfabetos.

Blaise de Vigenère publicó su descripción de un cifrado de autoclave parecido, pero más robusto, antes del reinado de Enrique III de Francia, en 1586. Más tarde, en el siglo XIX, la invención del cifrado dejó de atribuirse a Vigenère.

El cifrado de Vigenère ganó una gran reputación por ser excepcionalmente robusto. Incluso el escritor y matemático Charles Lutwidge Dodgson (Lewis Carroll) dijo que el cifrado de Vigenère era irrompible en un artículo titulado "The Alphabet Cipher" para una revista infantil. En 1917, la revista Scientific American afirmó que el cifrado de Vigenère era imposible de romper. Esta reputación era inmerecida, considerando que el método Kasiski resolvió el cifrado en el siglo XIX, y que algunos criptoanalistas habilidosos pudieron romper ocasionalmente el cifrado en el siglo XVI.

A lo largo del siglo XIX, se propusieron distintas variaciones sobre este sistema, pero que no incrementaban significativamente la seguridad y presentaban similares vulnerabilidades; entre estas estaban las siguientes:[1]

  • Método de Auray
  • Método de Beaufort
  • Método de Gronsfeld

Gilbert Vernam trató de arreglar el cifrado (creando el cifrado Vernam-Vigenère en 1918), pero a pesar de sus esfuerzos, el cifrado sigue siendo vulnerable al criptoanálisis.

Funcionamiento

mensaje:      P A R I S  V A U T  B I E N  U N E  M E S S E
clave:        L O U P L  O U P L  O U P L  O U P  L O U P L 
criptograma:  A O M X D  K U K E  P C T X  J H T  W S N I O

En este alfabeto solo existen 27 letras:

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
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

En términos matemáticos, puede expresarse la función de cifrado como:

Donde es la letra en la posición del texto a cifrar, es el carácter de la clave correspondiente a , pues se encuentran en la misma posición, y es el tamaño del alfabeto. En este caso .

Para descifrar realizamos la operación inversa:

Cuando

Cuando

Donde es el carácter en la posición del texto cifrado, viene siendo el carácter de la clave correspondiente a , y el tamaño del alfabeto.

Se observa que a una misma letra en el texto plano le pueden corresponder diferentes letras en el texto cifrado.

Código en Batch para Windows

Un ejemplo para usar se debe guardar como .cmd para ejecutar el programa y ver su funcionamiento.

@echo off 
title ENCRIPT VIGENERE- -coded by YURI
Rem This code encript your password to Vigenere system
Rem o :: comment
setlocal enabledelayedexpansion
color 0A 
Rem color 0A 0=black and A=green Light colors of the console
set TheABC=nam 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
REM English system 26 Letters
@set /a "cont=-1"
 
set abc[0].Letters=Letters
set abc[0].ID=ID
 
set key[0].Letters=Letters
set key[0].ID=ID
 
set pass[0].Letters=Letters
set pass[0].ID=ID
 
set encrypt[0].Letters=Letters
set encrypt[0].ID=ID
 
set "strEn="
 
(for %%v in (%TheABC%) do (
	set /a "cont=1+!cont!"
	set "abc[!cont!].Letters=%%v"
	set "abc[!cont!].ID=!cont!"
))
 
@ECHO. 
::Echo. REM Line steps
echo "Key"
@ECHO.
set /p key=
 
echo "Password"
@ECHO.
set /p pass=
:: Echo the length of TEST
::call :strLen pass
 
:: call the function strLen to lenght the string
call :strLen key keylen
call :strLen pass passlen
 
set /a q=%passlen% * 1000 / %keylen%
::echo q=%q:~0,-3%.%q:~-3%
REM number with decimal bc the batch system its only integer system
set /a dec=%q:~-3%
set /a int=%q:~0,-3%
 
if %dec% EQU 0 (
	set /a rounded=%int%-1
)
REM its the times of repeat the key lenght like keykeykey n number depends of password lentgh
if %dec% NEQ 0 (
	set /a rounded=%int%
)
 
set "name=%key%"
set "num=-1"
set "chain[0]=1"
 
REM string to char key
:loop
	set /a "num=num+1"
	call set "name2=%%name:~%num%,1%%"
	if defined name2 (
		::echo(%name2%,%num%
		set chain[%num%]=%name2%
		goto :loop
	)	
 
set "nametwo=%pass%"
set "numtwo=-1"
set "chaintwo[0]=1"
@set /a "con=0"
 
REM string to char password
:loopone
	set /a "numtwo=numtwo+1"
	call set "nameto=%%nametwo:~%numtwo%,1%%"
	if defined nameto (
		set /a "con=!numtwo!+1"
		::echo(%nameto%,%numtwo%
		set chaintwo[!con!]=%nameto%
		goto :loopone
)
 
@set /a "nan=%keylen%-1"
set /a "keyString[0]=1"
@set /a "l=0"
 
REM string to char password
for /l %%n in (0,1,%rounded%) do ( 
	@set /a "m=0"
	for /l %%m in (0,1,%nan%) do ( 
		set /a "l=1+!l!"
		set "keyString[!l!]=!chain[%%m]!"
		if !l! EQU %passlen% (
			goto :continue
		)
	)
)
 
REM for to debug the arrays
::for /l %%t in (0,1,%passlen%) do ( 
::	echo !keyString[%%t]!
::)
 
:continue
REM save the arrays 
for /l %%n in (1,1,%passlen%) do (
	set "key[%%n].Letters=!keyString[%%n]!"
	set "pass[%%n].Letters=!chaintwo[%%n]!"
)
 
REM find ids for key
for /l %%z in (1,1,%passlen%) do (
	call :findStrAndSetId !key[%%z].Letters! abc id
	set "key[%%z].ID=!id!"
)
REM find ids for pass
for /l %%x in (1,1,%passlen%) do (
	call :findStrAndSetId !pass[%%x].Letters! abc id
	set "pass[%%x].ID=!id!"
)
REM find the Encrypted ids 
for /l %%y in (1,1,%passlen%) do (
	call :moduler !key[%%y].ID! !pass[%%y].ID! encryptID
	set "encrypt[%%y].ID=!encryptID!"
)
 
@ECHO.
REM find the Encrypted Letters
for /l %%w in (1,1,%passlen%) do (
	call :findIdAndSetStr !encrypt[%%w].ID! abc str
	set "encrypt[%%w].Letters=!str!"
)
 
REM Finally char to string Encrypted password
for /l %%v in (1,1,%passlen%) do (
	set "strEn=!strEn!!encrypt[%%v].Letters!"
)
REM Print the var
call echo Encript=%strEn%
echo !strEn!
 
REM Keep your windows batch open
pause 
 
REM function string lenght
:strLen  strVar  [rtnVar]
setlocal disableDelayedExpansion
set len=0
if defined %~1 for /f "delims=:" %%N in ('"(cmd /v:on /c echo(!%~1!&echo()|findstr /o ^^"') do set /a "len=%%N-3"
endlocal & if "%~2" neq "" (set %~2=%len%) else echo %len%
exit /b
 
REM function find the id from the Letters
:findStrAndSetId
set abc = Inner
set "%~2=%abc%"
for /L %%i in (1 1 26) do  (
	if /I "%~1"=="!%~2[%%i].Letters!" (
		set /a "%~3=!%~2[%%i].ID!"
		goto :next
	)	
)
:next
exit /b
 
REM function find the Letters from id
:findIdAndSetStr
set abc = Inner
set "%~2=%abc%"
for /L %%j in (1 1 26) do  (
	if %~1 EQU !%~2[%%j].ID! (
		set %~3=!%~2[%%j].Letters!
		goto :next1
	)	
)
:next1
exit /b
 
REM the formule to find encrypted letters
:moduler
	set /a sum=%~1+%~2
	set /a mod=%sum% %% 26
	set /a div=%sum% * 1000/26
	
	REM this formule have 2 errors when 
	REM the sum is equal to 26 and the  
	REM mod is 26 in english language 
	REM the modular is zero but this
	REM error can solved bc in all cases 
	REM the Letter is y 
	if %mod% EQU 0 ( 
		set /a %~3=%div:~0,-3%*25
		goto :jump
	)
	REM and z bc the module 27 mod 26  
	REM its to much decimals in it 
	REM number in batch cant have 
	REM decimal like another languages
	if %sum% EQU 27 ( 
		set /a %~3=%div:~0,-3%*26
		goto :jump
	)
	
	set /a mult=%div:~-3%*26
	set /a %~3=%mult%/1000
	
	:jump
exit /b

Ejemplo código en C

#include <ctype.h>
#include <stdio.h>
#include <string.h>
void cifrarVigenere(char* texto, char* clave) {
    int textoLen = strlen(texto), claveLen = strlen(clave), i, j;
    char nuevaClave[textoLen], cifradoTexto[textoLen];
    // Generar nueva clave en caso de que la longitud del texto original y la clave no coincidan
    for(i = 0, j = 0; i < textoLen; ++i, ++j){
        if(j == claveLen)
            j = 0;
        nuevaClave[i] = clave[j];
    }
    nuevaClave[i] = '\0';
    // Cifrado
    for(i = 0; i < textoLen; ++i)
        cifradoTexto[i] = ((texto[i] + nuevaClave[i]) % 26) + 'A';
    cifradoTexto[i] = '\0';
    printf("Texto cifrado: %s\n", cifradoTexto);
}
int main() {
    char texto[] = "TEXTOPLANO";
    char clave[] = "CLAVE";
    cifrarVigenere(texto, clave);
    return 0;
}

Vulnerabilidades

Las principales vulnerabilidades del método de Vigenère derivan de su regularidad. Al proponer una serie de cifras cíclicas, el analista simplemente tiene que buscar una serie de grupos de letras que se repitan periódicamente. Al comparar las distintas repeticiones, puede deducir el número de letras de la clave, tras lo cual basta con separar esos alfabetos distintos y aplicar el análisis de frecuencias a cada uno de esos alfabetos (Método Kasiski).

Otra posibilidad sería aplicar el índice de coincidencia para encontrar el número de letras de la clave.

Véase también

Enlaces externos

Referencias

  1. J. G. Carmona, Tratado de criptografía con aplicación especial al ejército, Ministerio de Defensa, 2011.