miércoles, 15 de junio de 2011

La encriptacion

La Encriptación, es un tema de la programación bien interesante, de hecho se trata de una alta ciencia de la informática, que pasa por arte, inclusive hoy se trata de una tecnología. Encriptación es una palabra rara en español, quizá fea, no obstante se emplea en documentación técnica.
Buscando en el cajón de los recuerdos, encontré un par de procedimientos para Codificación / Decodificación con QuickBasic. Desaforadamente desconozco al programador de tales procedimientos. Después de traducir las rutinas para que trabajasen en Visual Basic me di cuenta que tenían fallas de programación, sin embargo la documentación del código me llevo a captar la idea del autor y ponerla a funcionar perfectamente. Tales procedimientos se exponen en este documento.




Algo de Teoría
Recuerdo que alguien comentaba que codificar era muy sencillo, simplemente cambias unas letras por otras, y el receptor del mensaje conoce este secreto. También, aumentar o disminuir un número discreto a los códigos ASCII, suele ser otra sugerencia. Estas estrategias pasan a ser infantiles tratamientos del problema, y no presentan problema alguno para un decodificador experto y malo.
La encriptación se hace a través de la aplicación de cierto tratamiento a los códigos ASCII de los mensajes, de manera que el tratamiento inverso será el único camino práctico para decodificar el mensaje.
¿Cómo se mantiene indescifrable una cadena codificada?. Se trata de combinar la clave de encriptación con el mensaje de manera que las probabilidades de decodificar el mensaje, sin conocer la clave, sean virtualmente infimas, es decir, el tan prolongado el trabajo de desciframiento que no existen esperanzas próximas. Por ejemplo cuando un cristal ornamental se rompe violentamente, es casi imposible volver a juntar las piezas para obtener la pieza original.
Como una cita teórica, uno de los algoritmos de codificación se basa en la función números primos. Por ejemplo resulta fácil multiplicar dos números primos, sean a = 11927 y b = 20903, de manera que a • b = c = 249310081. Pero resulta muy difícil determinar a y b a partir de c. Matemáticamente esto se hace a través del procedimiento conocido como Descomposición Factorial. En el ejemplo c viene a ser la codificación, mientras a y b son la clave de decodificación. Esta estrategia es la base de un ingenioso y sofisticado sistema de encriptación llamado Criptosistema RSA (en honor a sus autores). de hecho este es el mejor sistema de encriptación y es posible que sea aplicado en las comunicaciones masivas de Internet en un futuro. Siguiendo con mí ejemplo, en un caso real, se trata de cifras de alrededor de 250 dígitos, lo cual teóricamente requiere de millones de años para descomponer factorialmente. Una anécdota citada en el libro Camino al Futuro (2ª edición) de Mr. Gates, cuenta que un reto publico de descifrar una clave de 129 dígitos fue superado al coordinar un trabajo de varias computadoras e Internet, para finalmente lograr la respuesta en menos de un año. En el reto los autores predecían que su mensaje jamás sería desvelado. El libro mencionado hace una exposición más detallada de este tema. Por supuesto, este articulo no llegará tan lejos.

Dos Procedimientos de Encriptación
La Encriptación tiene dos elementos: Un mensaje, y una clave privada de acceso entre el emisor y el receptor, con la cual se puede descifrar el mensaje. El procedimiento de encriptación produce un mensaje o archivo cifrado. Presento dos procedimientos escritos en Visual Basic, catalogados como verdaderas maneras de encriptación.

Modelo EncryptionString
EncryptionString, es un clásico sistema el cual toma el mensaje y una clave del usuario, y a través de una combinación de estos dos parámetros se produce una cadena codificada. Mantengo la explicación original del método:
Texto a codificar:         ENCRYPTION
Caracteres del Texto:      E   N   C   R   Y   P   T   I   O   N
Códigos ASCII:             69  78  67  82  89  80  84  73  79  78
Contraseña KEY:            K   E   Y   K   E   Y   K   E   Y   K
Caracteres de KEY:         75  69  89  75  69  89  75  69  89  75
Suma de Códigos ASCII:     144 147 156 157 158 169 159 142 168 153
En caracteres:                   œ      ?   ©   Ÿ   ?   ¨  

Texto codificado:          “œ?©Ÿ?¨™
El modo para usar la función EncryptionString es el siguiente:
'//Codifica
TextoCodificado = EncryptString(TextoOriginal, Contraseña, ENCRYPT)

'//Decodifica
TextoOriginal = EncryptString(TextoCodificado, Contraseña, DECRYPT)
La ventaja de esta técnica es que es muy flexible de usar e intuitiva. Sin tener la máxima seguridad, es muy segura. Escribir un programa para encriptar archivos resulta bastante simple por aquello de la contraseña. No ocurre lo mismo con el siguiente procedimiento: ChrTran.
El código de EncryptionString es el siguiente:
DefInt A-Z
Option Explicit

'//For Action parameter in EncryptString
Public Const ENCRYPT = 1, DECRYPT = 2

'---------------------------------------------------------------------
' EncryptString
' Modificado por Harvey T.
'---------------------------------------------------------------------
Public Function EncryptString( _
    UserKey As String, Text As String, Action As Single _
    ) As String
    Dim UserKeyX As String
    Dim Temp     As Integer
    Dim Times    As Integer
    Dim i        As Integer
    Dim j        As Integer
    Dim n        As Integer
    Dim rtn      As String
   
    '//Get UserKey characters
    n = Len(UserKey)
    ReDim UserKeyASCIIS(1 To n)
    For i = 1 To n
        UserKeyASCIIS(i) = Asc(Mid$(UserKey, i, 1))
    Next
       
    '//Get Text characters
    ReDim TextASCIIS(Len(Text)) As Integer
    For i = 1 To Len(Text)
        TextASCIIS(i) = Asc(Mid$(Text, i, 1))
    Next
   
    '//Encryption/Decryption
    If Action = ENCRYPT Then
       For i = 1 To Len(Text)
           j = IIf(j + 1 >= n, 1, j + 1)
           Temp = TextASCIIS(i) + UserKeyASCIIS(j)
           If Temp > 255 Then
              Temp = Temp - 255
           End If
           rtn = rtn + Chr$(Temp)
       Next
    ElseIf Action = DECRYPT Then
       For i = 1 To Len(Text)
           j = IIf(j + 1 >= n, 1, j + 1)
           Temp = TextASCIIS(i) - UserKeyASCIIS(j)
           If Temp < 0 Then
              Temp = Temp + 255
           End If
           rtn = rtn + Chr$(Temp)
       Next
    End If
   
    '//Return
    EncryptString = rtn
End Function

Modelo ChrTran
ChrTran es violentamente complicado de violar, de hecho imposible. Virtualmente las probabilidades de descifrar un mensaje son del orden de 255! (255 factorial), un numero sin fin en la práctica (por ejemplo las calculadoras comunes soportan solo hasta 69!).
Tengo que confesar que tuve que reescribir ChrTran porque presentaba errores de programación y mucho código para optimizar, el resultado es sorprendente. Ni que decir que no tenía en cuenta que en español usamos tildes y eñes.
Como su abreviación lo dice ChrTran transpone caracteres, usa dos claves de 255 caracteres (la carta ASCII) y produce un texto codificado de origen aleatorio. Toma cada carácter del texto, encuentra su posición en la primera clave, e intercambia este carácter por el carácter en la misma posición de la segunda clave. Es complicado de asimilar.
Lo más difícil de ChrTran es el manejo de las claves. La primera clave (la sarta de búsqueda) podría ser publica (mejor debiera decir debe ser publica). Mientras que la segunda clave es una sarta aleatoria de la carta ASCII.
El modo de manejar ChrTran es el siguiente:
ClaveAleatoria = RandomChart()
   
'// Se podría usar la sarta de búsqueda, ClaveDeBúsqueda, como
'// otra cadena aleatoria con ClaveDeBúsqueda = RandomChart()
'// aqui se mantiene un nivel de Encriptación flexible, más no
'// inseguro, al hacer ClaveDeBúsqueda como la secuencia 0 a 255
'// de la carta ASCII:
For i = 0 To 255
    ClaveDeBúsqueda = ClaveDeBúsqueda + Chr$(i)
Next
   
'//Codifica
TextoCodificado = ChrTran(TextoOriginal, ClaveDeBúsqueda, ClaveAleatoria)

'//Decodifica
TextoOriginal= ChrTran(TextoCodificado, ClaveAleatoria, ClaveDeBúsqueda)
En la primera línea se usa RandonChart, la cual es una función que retorna la carta ASCII en un orden aleatorio.
Como posiblemente se deduce, usar ChrTran para escribir un programa que trabaje encriptación, representa una labor bastante especializada, pero por supuesto nada del otro mundo.
El código de ChrTran es el siguiente:
DefInt A-Z
Option Explicit

'//---------------------------------------------
'// Return a random string of ASCII Chart.
'// Used by ChrTran. By Harvey T.
'//---------------------------------------------
Public Function RandomChart() As String
    Dim Char    As String
    Dim RndStr  As String
    Dim n       As Integer
   
    Randomize Timer
    Do
       Char = Chr$(Int(Rnd * 256))
       If InStr(RndStr, Char) = 0 Then
          n = n + 1
          RndStr = RndStr + Char
       End If
    Loop Until n = 256
       
    RandomChart = RndStr
End Function

'---------------------------------------------------------------------
' ChrTran
' Optimizing by Harvey T.
'---------------------------------------------------------------------
Public Function ChrTran(Text As String, SStr As String, EStr As String) As String
    Dim i   As Integer
    Dim rtn As String
   
    For i = 1 To Len(Text)
        rtn = rtn + Mid$(EStr, InStr(SStr, Mid$(Text, i, 1)), 1)
    Next
    ChrTran = rtn
End Function
Aplicación de Ejemplo
La figura que encabeza este articulo muestra la cara de la aplicación EncryptProject, la cual es una herramienta que utiliza las técnicas de encriptación descritas y lo creé con el propósito de proteger código Visual Basic. Es decir, supón que trabajas en un proyecto grande, en un equipo de programación y deseas mantener en privado ciertos módulos. Generalmente yo organizo mis proyectos por módulos, en carpetas aparte, así, EncryptProject tiene la finalidad de encriptar los módulos Visual Basic de esta carpeta. Así, cuando voy a trabajar, decodifico, cuando me voy encripto.
Si desea usar EncryptProject , debe tener en cuanta esta precuación:
Backup your files (in another disc or with password) before encrypt project.
No forget your password, it's without it reversing !
Encrypt only work over: Bas, Frm, Cls, Ctl, html files
Es decir, como una percusión, debiera tener al menos una copia aparte del proyecto. Pero no se atemorice, el programa es seguro, lo peor que le podría pasar al que lo use es olvidar la contraseña (EncryptProject  pide verificación de la contraseña antes de codificar). Recomiendo para empezar, hacer una prueba sencilla con un proyecto simple.
Dos pasos y salimos. Hagamos una prueba simple. Cree una carpeta, copie o cree u proyecto Visual Basic en ella.

Encriptando
Abra EncryptProject, y escriba la trayectoria completa de la carpeta (si lo prefiere, arrastre un archivo cualquiera de la carpeta desde el Explorador de archivos de Windows a la caja de texto Project Folder).
Escriba la contraseña y use el comando [Encrypt]. Se pedirá la verificación de la contraseña. Después de confirmar, se encriptará el proyecto.

Encriptación de Datos
Como sabemos, en un Sistema de Comunicación de Datos, es de vital importancia
asegurar que la Información viaje segura, manteniendo su autenticidad, integridad,
confidencialidad y el no repudio de la misma entre otros aspectos.
Estas características solo se pueden asegurar utilizando las Técnicas de Firma Digital
Encriptada y la Encriptación de Datos.
Métodos de encriptación:
Para poder Encriptar un dato, se pueden utilizar tres procesos matemáticos diferentes:
Los algoritmos HASH, los simétricos y los asimétricos.
·         Algoritmo HASH:
Este algoritmo efectúa un cálculo matemático sobre los datos que
constituyen el documento y da como resultado un número único
llamado MAC. Un mismo documento dará siempre un mismo
MAC.
·         Algoritmos Simétricos:
Utilizan una clave con la cual se encripta y desencripta el
documento. Todo documento encriptado con una clave, deberá
desencriptarse, en el proceso inverso, con la misma clave. Es
importante destacar que la clave debería viajar con los datos, lo que
hace arriesgada la operación, imposible de utilizar en ambientes
donde interactuan varios interlocutores.
·         Algoritmos Asimétricos (RSA):
Requieren dos Claves, una Privada (única y personal, solo conocida
por su dueño) y la otra llamada Pública, ambas relacionadas por una
fórmula matemática compleja imposible de reproducir. El concepto
de criptografía de clave pública fue introducido por Whitfield Diffie
y Martin Hellman a fin de solucionar la distribución de claves
secretas de los sistemas tradicionales, mediante un canal inseguro.
El usuario, ingresando su PIN genera la clave Publica y Privada necesarias. La clave
Publica podrá ser distribuida sin ningún inconveniente entre todos los interlocutores. La
Privada deberá ser celosamente guardada.
Cuando se requiera verificar la autenticidad de un documento enviado por una persona se
utiliza la Clave Publica porque el utilizó su Clave Privada.
Firma Digital
Descripción
El concepto de firma digital nació como una oferta tecnológica para acercar la operatoria
social usual de la firma ológrafa (manuscrita) al marco de lo que se ha dado en llamar el
ciberespacio o el trabajo en redes.
Es la transformación de un mensaje utilizando un sistema de cifrado asimétrico de manera
que la persona que posee el mensaje original y la clave pública del firmante, pueda
establecer de forma segura, que dicha transformación se efectuó utilizando la clave
privada correspondiente a la pública del firmante, y si el mensaje es el original o fue
alterado desde su concepción.
Las transacciones comerciales y el hecho de tener que interactuar masiva y
habitualmen6te por intermedio de redes de computadoras le dio lugar al concepto. Pero
sólo después que los especialistas en seguridad y los juristas comenzaran a depurarlo
alcanzó un marco de situación como para ocupar un lugar en las actuaciones entre
personas (jurídicas o reales).
Se intenta hacer coincidir el modelo de firma digital con los requerimientos y virtudes que
debe tener una firma y así darle validez a esta mecánica. El fin es el mismo de la firma
ológrafa: dar asentimiento y compromiso con el documento firmado.
El papel es el medio de almacenamiento, y el mecanismo es alguno de los tipos de
impresión posibles (tinta, láser, manuscrito, etc.). Esta cualidad física le da entidad al
documento, contiene sus términos, conceptos y sentidos de una manera perdurable, y al
ser un elemento físico cualquier alteración dejará “señales” identificables.
Pero estas mismas cualidades traen aparejados inconvenientes que el uso de sistemas de
computación podría evitar. Ciertamente los papeles ocupan lugar y pesan demasiado,
resulta complejo y molesto buscar información en ellos (requiriendo de la acción humana
ya sea al archivarlos y/o al rescatarlos), y el compartir los documentos también resulta
inconveniente.
Ventajas Ofrecidas por la Firma Digital
El uso de la firma digital satisface los siguientes aspectos de seguridad:
·         Integridad de la información: la integridad del documento es una protección contra la
modificación de los datos en forma intencional o accidental. El emisor protege el documento,
incorporándole a ese un valor de control de integridad, que corresponde a un valor único,
calculado a partir del contenido del mensaje al momento de su creación. El receptor deberá
efectuar el mismo cálculo sobre el documento recibido y comparar el valor calculado con el
enviado por el emisor. De coincidir, se concluye que el documento no ha sido modificado
durante la transferencia.
·         Autenticidad del origen del mensaje: este aspecto de seguridad protege al receptor del
documento, garantizándole que dicho mensaje ha sido generado por la parte identificada
en el documento como emisor del mismo, no pudiendo alguna otra entidad suplantar a un
usuario del sistema. Esto se logra mediante la inclusión en el documento transmitido de un
valor de autenticación (MAC, Message autentication code). El valor depende tanto del
contenido del documento como de la clave secreta en poder del emisor.
·         No repudio del origen: el no repudio de origen protege al receptor del documento de la
negación del emisor de haberlo enviado. Este aspecto de seguridad es más fuerte que los
anteriores ya que el emisor no puede negar bajo ninguna circunstancia que ha generado dicho
mensaje, transformándose en un medio de prueba inequívoco respecto de la responsabilidad
del usuario del sistema.
Aspectos técnicos
A diferencia de la firma manuscrita, que es un trazo sobre un papel, la firma digital
consiste en el agregado de un apéndice al texto original, siendo este apéndice, en
definitiva, la firma digital; al conjunto formado por el documento original más la firma
digital se lo denominará mensaje.
Este apéndice o firma digital es el resultado de un cálculo que se realiza sobre la cadena
binaria del texto original.
En este cálculo están involucrados el documento mismo y una clave privada (que,
generalmente, pertenece al sistema de clave pública-privada o sistema asimétrico) la cual
es conocida sólo por el emisor o autor del mensaje, lo que da como resultado que para
cada mensaje se obtenga una firma distinta, es decir, a diferencia de la firma tradicional,
la firma digital cambia cada vez con cada mensaje, porque la cadena binaria de cada
documento será distinta de acuerdo a su contenido.
A través de este sistema podemos garantizar completamente las siguientes propiedades de
la firma tradicional:
·         Quien firma reconoce el contenido del documento, que no puede modificarse con
posterioridad (integridad).
·         Quien lo recibe verifica con certeza que el documento procede del firmante. No
es posible modificar la firma (autenticidad).
·         El documento firmado tiene fuerza legal. Nadie puede desconocer haber firmado
un documento ante la evidencia de la firma (no repudio).
Este sistema utiliza dos claves diferentes: una para cifrar y otra para descifrar. Una es la
clave pública, que efectivamente se publica y puede ser conocida por cualquier persona;
otra, denominada clave privada, se mantiene en absoluto secreto ya que no existe motivo
para que nadie más que el autor necesite conocerla y aquí es donde reside la seguridad del
sistema.
Ambas claves son generadas al mismo tiempo con un algoritmo matemático y guardan
una relación tal entre ellas que algo que es encriptado con la privada, solo puede ser
desencriptado por la clave pública.
Resumiendo, la clave privada es imprescindible para descifrar criptogramas y para firmar
digitalmente, mientras que la clave pública debe usarse para encriptar mensajes dirigidos
al propietario de la clave privada y para verificar su firma.
Si bien no se trata de un tema estrictamente técnico, es conveniente aclarar que en tiempo
de generación de cada par de claves, pública y privada, podría intervenir otra clave que es
la de la Autoridad Certificante que provee la garantía de autenticidad del par de claves
generadas, así como también, su pertenencia a la persona cuya propiedad se atribuye.
Este esquema se utiliza en intercambios entre entidades cuando se trata de transferencias
electrónicas de dinero, órdenes de pago, etc. donde es indispensable que las transacciones
cumplan con los requisitos de seguridad enunciados anteriormente (integridad,
autenticidad y no repudio del origen), pero no se satisface el concepto de confidencialidad
de la información (secreto)