"La gaceta de Linux... haciendo de Linux algo un poco más divertido!"


Encriptando Datos en Formularios Web

Por: Mark Nielsen

Traducción al Español por: Lucas Maximiliano Sola
el día 9 de Noviembre 2000, para La Gaceta de Linux


  1. Referencias
  2. Introducción
  3. Utilizando Blowfish
  4. Conversión de Llaves Encriptadas a Hexadecimal
  5. Métodos de Encriptación y Desencriptación
  6. ¿Por qué hacer estas cosas?
  7. Conclusión

Referencias

  1. http://www.perl.com/CPAN-local/modules/by-category/14_Security_and_Encryption/Crypt/Crypt-Blowfish-2.06.readme
  2. http://www.perl.com/pub/doc/manual/html/pod/perlfunc/pack.html

Introducción

Debe haber momentos en donde usted quiere enviar datos encriptados a un usuario en su servidor web. Por ejemplo, si usted quiere esconder el id numérico de una cuenta. Sin embargo, hay un problema en el envío de datos encriptados, es binario. Además, no hay muchos paquetes que faciliten la encriptación datos en Perl.

Utilizando Blowfish

Blowfish es el más módulo de encriptación más fácil de utilizar en Perl. No posee ninguna restricción de licencias. Creo que algunos otros módulos recientemente también perdieron sus restricciones, pero siempre voy con el software éticamente puro si es tan bueno como el otro software poco ético.

Aquí hay una forma fácil de encriptar y luego desencriptar los datos. Advierta, que no imprimo la cadena binaria encriptada porque no será imprimible.

use Crypt::Blowfish;

my $Blowfish_Key = "Una contraseña extremadamente tonta que usted debería cambiar.";
my $Blowfish_Cipher = new Crypt::Blowfish $Blowfish_Key;

  ### Recuerde, la sentencia tiene que ser de 8 caracteres de largo por lo menos
my $Sentence = "DumbWord";
my $Encrypted = $Blowfish_Cipher->encrypt($Sentence);
my $Decrypted = $Blowfish_Cipher->decrypt($Encrypted);

print "Do the next two lines match?\n";
print "$Sentence\n";
print "$Decrypted\n";

Conversión de Llaves Encriptadas a Hexadecimal

"pack" y "unpack" pueden ser un poco confusos de usar en Perl. Básicamente, ellos convierten datos en diferentes formatos. Como convertir caracteres en su código ASCII numérico equivalente o convertir números hexadecimales en enteros, etc.

Todo lo que queremos hacer es convertir datos binarios en datos hexadecimales. ¿Por qué son importantes los datos hexadecimales? Son alfanuméricos y no estropearán a un navegador con caracteres extraños. No hay seguridad en la utilización de hexadecimales, pero son compacto, y siempre son una cadena fija. Convierte cada caracter en dos caracteres hexadecimales (o números). Siempre teniendo una longitud exacta por caracter que los hace fácil de convertir nuevamente en datos binarios.

Aquí hay un simple comando para convertir una sentencia en hexadecimal, y luego volverla a convertir en texto.

my $Sentence = "Esta es una sentencia tonta.\n";
print "$Sentence\n";
my $Hex = unpack("H*",$Sentence);
print "$Hex\n";
my $Sentence2 = pack("H*",$Hex);
print "$Sentence2\n";

Métodos de Encriptación y Desencriptación para Páginas Web con CGI

Aquí una vieja y pequeña versión de lo que utilizamos en gnujobs.com, y no posee un método "new". Este es un paquete simple. Aquí está como usted puede llamar los métodos:

Primero, asumo que usted está utilizando mod_perl. En su directorio raíz para el servidor web apache, cree este directorio,

mkdir -p lib/perl/MyPackage
Luego copie el módulo siguiente en la locación lib/perl/MyPackage/Misc.pm.

Para encriptar datos,

use MyPackage::Misc;
my $Data = "Tan sólo una sentencia tonta que quiero encriptar";
my $Encrypted = MyPackage::Misc->Encrypt($Data);

Para desencriptar la información,
use MyPackage::Misc;
my $Decrypted = MyPackage::Misc->Decrypt($Encrypted);

Y aquí están los métodos. Usted debería personalizar estos módulos según sus necesidades. Mantuve $Blowfish_Cipher como una variable global para el paquete para que sólo necesite ser compilado una sola vez. Creo que puedo adicionalmente patentarlo con GPL sólo por promover GPL. Aquí está la licencia GNU GPL (versión texto de este listado)

#!/usr/bin/perl

# Copyright (C) 2000 Mark E. Nielsen at GNUJobs.com

# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

# Web-Encrypt-Example version 0, Copyright (C) 2000 Mark E. Nielsen at GNUJobs.com
# Web-Encrypt-Example comes with ABSOLUTELY NO WARRANTY.
# This is free software, and you are welcome
# to redistribute it under certain conditions.

# The Computer Underground, Inc., hereby disclaims all copyright
# interest in the program `Web-Encrypt-Example'
# written by Mark E. Nielsen.
# Mark E. Nielsen, President of The Computer Underground

package MyPackage::Misc;

use strict;
use Crypt::Blowfish;

my $Blowfish_Key = "An extremely dumb password you should change.";
my $Blowfish_Cipher = new Crypt::Blowfish $Blowfish_Key;

#-----------------------------------
sub Encrypt
{
my $self = shift;
my $String = shift;

my $Temp = $String;
my $Encrypted = "";
while (length $Temp > 0)  
  {
    ### If less than 8 characters, padd it with tabs
  while (length $Temp < 8) {$Temp .= "\t";}
    ### Ecnrypt the 8 length segment
  my $Temp2 = $Blowfish_Cipher->encrypt(substr($Temp,0,8));
    ### Add it to the end
  $Encrypted .= $Temp2; 
    ### If it is 8 or less, abort, otherwise get the next segment
  if (length $Temp > 8) {$Temp = substr($Temp,8);} else {$Temp = "";}
  }

my $Unpacked = unpack("H*",$Encrypted);

return ($Unpacked);
}

#--------------------------------
sub Decrypt
{
my $self = shift;
my $String = shift;

my $Packed = pack("H*",$String);

my $Temp = $Packed;
my $Decrypted = "";
while (length $Temp > 0)  
  {
  my $Temp2 = substr($Temp,0,8);
    ### In theory, we could up with less than 8 characters, check
  if (length $Temp2 == 8) 
    {
    my $Temp3 = $Blowfish_Cipher->decrypt($Temp2);
    $Decrypted .= $Temp3;
    } 
  if (length $Temp > 8) {$Temp = substr($Temp,8);} else {$Temp = "";}
  }
   ### Getting rid of tabs at the end, which could be a bad thing
   ### but is how I did it. 
$Decrypted =~ s/\t+$//g;

return ($Decrypted);
}

NOTA: Hay una cosa especial que usted debe hacer cuando desencripte información. Verifique para ver si contiene datos válidos. Si son numéricos, asegúrese de que sean números. Usualmente una idea elegante es siempre asumir que el número es positivo y menor que un billón, y hacer algo como esto,

my $Error = 1;
if (($Value >0) && ($Value < 1000000000)) {$Error = 0;}
if ($Error == 1) {print "Maldición, esto apesta, no son datos válidos, hasta luego!"; exit;}

¿Por qué hacer estas cosa?

La necesidad de encriptar datos para que la gente no pueda poner valores arbitrarios puede ser muy útil de vez en cuando. A condición que, un servidor web nunca debería ser configurado para permitirle a la gente poner valores arbitrarios, pero algunas veces si usted no es cuidadoso, la gente puede descargar toda la información fuera de su base de datos con sólo cambiar los identificadores únicos en un formulario web. A la mayoría de la gente no le importa, pero a algunos sí.

Además, si está correctamente configurado, los datos encriptados no interfieren con la experiencia en la web de una persona si usted mantiene los datos encriptados en campos ocultos en la página web.

Si usted desea mandar un mensaje de correo a un usuario para ver datos en su sitio web, enviar un mensaje de correo con un enlace que contiene datos encriptados puede ser una manera de proteger a la gente de entender cómo funciona su página web. No lo protege a usted demasiado, pero mientras más irritante lo haga usted, lo más probable es que algunos no se molestarán en tratar de entender cómo hace usted las cosas.

Conclusión

No he testeado PHP o Python para ver si ellos poseen un módulo sencillo para encriptar datos. El único módulo que fue fácil de utilizar en Perl fue Blowfish. Fue doloroso conseguir que cualquier otro funcione con Perl. Si usted se atraviesa con cualquiera que sea fácil de utilizar, o más fácil que Blowfish, por favor déjemelo saber en info@gnujobs.com.


Copyright © 2000, Mark Nielsen. Licencia de Copia http://www.linuxgazette.com/copying.html
Publicado en la edición 59 de La Gaceta de Linux, Noviembre del 2000