Está en la página 1de 15

Universidad Nacional Autónoma de México

Facultad de Ingeniería

Proyecto 1
Estudiantes: Cruz Villegas Karime

Dìaz Valenzuela Juan Carlos

Santiago Villegas Fernando

Asignatura: Criptografìa

Clave: 2930

Profesora: Rocìo Alejandra Aldeco Pèrez

Grupo: 02

Carrera: Ingenierìa en Computaciòn

Semestre: 2022-2

Ciudad de Mèxico, 25 de abril de 2022

Introducción
La seguridad informática es la protección de los sistemas informáticos y los datos
que son almacenados en nuestro servidor, y, por supuesto, también los datos de acceso.

La seguridad informática nos permite abrir nuestros puestos informáticos a otros


usuarios fuera de la empresa para compartir nuestros conocimientos, consejos y
técnicas.

La importancia de la seguridad informática tiene como premisa principal la


conservación de la integridad de la información y el equipo en sí. Piensa en los virus
como algo dañino que puede dañar tu sistema operativo y dejar tu ordenador colgado o
muy lento, sin dejar trabajar con él. También, en el peor de los casos, podemos perder
parte o todos los datos de nuestro ordenador y ello sería un desastre para nuestra
productividad personal o profesional
Otra cuestión a tener en cuenta es el valor de la información en sí, los datos importantes
como tus cuentas bancarias, tus fotos y hasta tus gustos, todo ello es importante y debe
ser protegido, porque cabe la posibilidad de que alguien externo haga mal uso de ello.
Para este proyecto en específico revisaremos cuál es el mejor algoritmo de: Cifrado,
Hash, Firma digital, Verificación. Donde compararemos cuál es el mejor en cuestión de
tiempo de ejecución, utilizando una librería externa ya que nosotros no crearemos
ninguno de estos algoritmos, nos haremos cargo de conocer las entradas para que estos
algoritmos funcionan, metiéndonos de lleno en el funcionamiento interno de estos.

Para realizar el proyecto utilizamos el lenguaje de programación Python 3, ya


que en nuestra opinión es uno de los lenguajes más sencillos de programar y más
amigable para trabajar datos en arreglos, donde estos son los principales tipos de datos
que se manejan en esta librería y a pesar de las desventajas, las ventajas resultan más
favorables, la facilidad de implementar todos los algoritmos nos permite prescindir del
tiempo de ejecución ya python es uno de los lenguajes más lentos al ser interpretado y no
compilado, sin embargo, no se trata de una programa que sea ejecutado en tiempo real
sino cada que se quiera ver los resultados.

Para la implementación de estos algoritmos utilizamos de las librerías


“pycryptodome” y “cryptography”, en el caso de pycryptodome contiene la mayoría de
los algoritmos requeridos para este proyecto, es una librería la cual también tiene su
página web donde se encuentra toda la documentación de los algoritmos incluidos de
una forma bien organizada y fácil de encontrar, ya que los divide de forma parecida a la
que necesitamos. Además de los algoritmos de cifrado, hash, firmas, verificación, incluye
algoritmos para generar llaves públicas, llaves de diferentes longitudes de bits (ya que
dependiendo de la extensión de bits de cada algoritmos cambia esta extensión), lo cual
es muy útil ya que no tuvimos que utilizar otra librería o generar nuestro propio
algoritmo y cryptogrpahy también contiene muchos algoritmos pero no se ahondó lo
suficiente ya que sólo utilizamos esta librería para completar pycryptodome a la cual le
hacían falta dos algoritmos de ECDSA.

Por otro lado, también utilizamos numpy y matplotlib para poder realizar las
gráficas adecuadamente.

Utilizamos el lenguaje de Python pues era el que contenía estas librerías.

A continuación, se presenta la implementación general de cada uno de los algoritmos


analizados en este proyecto:

Para el caso de los algoritmos en pycriptodome tenemos:

● ChaCha20:

Para cifrar tenemos como parámetros la llave:

Figura 1. Generamos la llave de 32 bytes (236 bits).

Figura 2. Especificamos que utilizamos AES, es necesaria la llave.

Figura 3. Ciframos utilizando el vector el cual es el texto plano.


Figura 4. Para este caso es necesario un nonce, después acomodamos para fines de
representación.

Para descifrar tenemos los siguientes parámetros:

Figura 5. Es necesario extraer los datos de la lista cifrada, como el nonce, el texto
cifrado, la llave guardada anteriormente.

Figura 6. Con los datos extraídos anteriormente ciframos.

● AES-EBC

Tenemos como parámetros la llave:

Figura 7. Generamos la llave de 32 bytes (236 bits).

Creamos una llave de acuerdo al tipo de algoritmo el cual es EBC:

Figura 8. Especificamos que utilizamos AES, necesaria la llave y el “modo” del


algoritmo.

Figura 9. Para cifrar es necesario hacer un relleno para alinear el texto en claro, así
como el tamaño del bloque ingresado.

Figura 10. Para fines de representación.

Para descifrar tenemos los siguientes parámetros:


Figura 11. Extraemos los datos necesarios, como la lista de texto cifrado, utilizamos la
misma llave guardada y especificamos que es modo ECB.

Figura 12. Desciframos haciendo un unpad de los datos y utilizando el tamaño de la


llave.

● AES-GCM

Figura 13. Generamos la llave de 32 bytes (236 bits).

Figura 14. Para este algoritmo necesitamos ingresar un encabezado o header, indicamos
que vamos a utilizar AES con su respectiva llave y el “modo” GCM.

Figura 15. Ciframos utilizando cifrado digestivo el texto plano, junto con tag.

Figura 16. En tupla unimos k y v.

● RSA-OAEP:

Figura 17.- Creación de la llave para RSA-OAEP.

Figura 18.- Creación del cifrador a partir de la llave dada.

Figura 19.- Cifrado del mensaje.


Figura 20.- Descifrado del mensaje.

● RSA-PSS:

Figura 21.- Creación de la llave para RSA-PSS.

Figura 22.- Creación de un algoritmo hash.

Figura 23.- Aplicación del hash al mensaje.

Figura 24.- Firma del mensaje dada la llave y el hash.

Figura 25.- Verificación de la firma dada la llave y la firma.

● Algoritmos de SHA

Para la implementación de los algoritmos de SHA, tenemos lo siguiente:

Figura 26.- Importación de la librería y la versión correspondiente de SHA

Figura 27. Se manda a llamar la función a utilizar de la librería y se le pasa el vector


con el mensaje al que se le aplicará el Hash

Figura 28.- Creación del algoritmo

Figura 29. Va haciendo una actualización del hash, con los datos que se le pasaron, en
este caso con el vector inicial
NOTA: Se hace la misma implementación para cada una de las versiones de SHA, solo
cambia el nombre en la librería.

Figura 30. Funciones que se utilizaron de SHA en sus diferentes versiones

Para el caso de cryptography tenemos:

● ECDSA Prime Field 521:

Figura 31 .- Creación de la llave para una curva SECP521.

Figura 32.- Firma con la llave dado un mensaje y un algoritmo de hash.

Figura 33.- Obtención de la llave pública dada la llave.

Figura 34.- Verificación de la firma con la llave pública dada la firma, el mensaje y un
algoritmo de hash.

● ECDSA Binary Field 571:

Figura 35.- Creación de la llave dada una curva SECT571.

Figura 36.- Firma con la llave dado un mensaje y un algoritmo de hash.

Figura 37.- Obtención de la llave pública a partir de la llave.


Figura 38.- Verificación con la llave pública dada la firma, el mensaje y un algoritmo de
hash.

Sin embargo, no podíamos utilizar cualquier mensaje para encriptar, o firmar o hacer
hash, teníamos la restricción para RSA que el mensaje no puede ser más largo que su
llave, y como son de 2048 bits o 256 bytes, entonces los vectores creados los realizamos
inferiores a esta cifra. La propia librería toma como límite 215 bytes para RSA por lo
que creamos una serie de mensajes de diferentes longitudes hasta 212.

Está claro que en el día a día los algoritmos trabajan con textos más largos, sin
embargo, eso significaba realizar el algoritmo varias veces para un mismo mensaje, que
a grandes rasgos sería realizar el algoritmo para varios mensajes diferentes que tienen
sentido entre sí, por lo que nos limitamos a eso y creamos una cantidad considerable de
vectores. Los mostrados se utilizaron para todos los algoritmos, son 13 y van desde los 5
bytes hasta los 212 bytes.

Figura 39. Vectores de entrada

Figura 40. Repetición de vectores.

Para la ejecución usamos 130 vectores, donde se repiten cada 13 veces ya que
son los que tenemos ingresados, hicimos esto para no tener que ingresar 130 vectores
diferente o crear vectores aleatorios que no tendrían ningún significado para nosotros y
que en términos reales nunca o casi nunca sucederían y tratamos de tener algo más
factible en nuestros vectores. Además, el uso de 130 vectores no es solamente para
realizar 10 cada vector, sino que, dependiendo de la bibliografía estadística que se
consulte, 127 muestras se considera suficiente para considerar un muestreo adecuado y
se redondeo a 130, aunque en ocasiones obtenemos varios resultados de ejecución de 0
segundos , eliminamos los valores de ejecución de 0 de la lista con la siguiente línea de
código de acuerdo a su respectivo algoritmo:

Figura 41 , tiempos 0

Donde “tiempos” corresponde a la lista de tiempos de ejecución del algoritmo en


cuestión, eliminando de esta lista los que sean igual a 0.0, haciendo esto, eliminamos los
valores extremos inferiores que no nos son de ayuda para el promedio de ejecución.
La eliminación de los 0 realmente lo realizamos para que no nos afecte mucho el
cálculo del promedio ya que podemos considerar suponer dos cosas, el resultado ya lo
tenía calculado y por eso no se calculó de nuevo o no se realizó el cálculo, por lo que un
0 nos sesga mucho la salida.

Figura 42 , promedio de tiempos


Para calcular el tiempo promedio de ejecución utilizamos la librería “numpy”
con la función “np.mean” hacemos un promedio de ejecución de la lista de tiempos del
algoritmo en cuestión, donde toma el número de integrantes de dicha lista, los suma y los
divide entre dicho número para obtener así su promedio, los tiempos de ejecución ya son
los efectivos, donde eliminamos los 0, mencionado anteriormente.

Para un mejor entendimiento del comportamiento de cada uno de los algoritmos


tenemos gráficas de cada uno tales como las que se muestran a continuación.

Esta gráfica nos muestra el comportamiento de cada algoritmo de firma


dado un mensaje, ya que se trata de algoritmos complejos pero que dependen del
mensaje por lo que no debería de ser tanta la diferencia entre un mensaje de 5
bytes a uno de 212 bytes, pero existe dicha diferencia.
A pesar de que cada vez que se ejecuta el programa, las gráficas cambian,
los promedios no se mueven mucho y son muy similares a las siguientes:
Para los promedios donde los resultados son muy similares tenemos los siguientes
esquemas de caja y bigote.
Podemos apreciar como SHA2-384 y SHA2-512 son prácticamente iguales, mientras que
SHA3-384 tiene unos valores muy extremos que sesgan el promedio y lo incrementan un
poco y por último SHA3-512 tiene una ejecución muy buena dado que los valores
extremos no se alejan mucho. Está es la gráfica que representa este comportamiento.

Con ayuda de las gráficas del tiempo de ejecución y de los promedios podemos concluir
lo siguiente:

· Para encriptar el óptimo es: RSA-OEAEP

· Para descifrar el óptimo es: CHA CHA 20

· Para firmar el óptimo es: ECDSA 521

· Para verificar el óptimo es: RSA-PSS

· Para hashear el óptimo es: SHA3-512

Evidencia
Repositorio:

https://github.com/GombVF/Cripto

Conclusiones
Cruz Villegas Karime

La realización de este proyecto me ayudó a comprender cuáles son los datos y


herramientas que se necesitan para completar cada uno de los algoritmos, así como su
comportamiento en tiempo y en la manera en que realiza sus actividades. Usar las
implementaciones que ya existen, así como la documentación que nos proporciona la librería
que utilizamos fue de gran ayuda para un mejor entendimiento. Para la parte del tiempo de
ejecución fue un poco más difícil sacar conclusiones, debido a que los resultados no siempre
eran los esperados o eran demasiado similares, así que nos fijamos también en la seguridad que
dan cada uno de los algoritmos probados.

Díaz Valenzuela Juan Carlos

El proyecto me sirvió para tener un contacto más cercano con estos algoritmos, aunque
fueron revisados en clase no es lo mismo ver la teoría de estos, la cual es muy útil para
comprender su funcionamiento, a utilizarlos, ya que podemos ver las necesidades reales de
estos, ya sea generar una llave aleatoria con un tamaño específico, devolver el texto cifrado de
una forma específica para que la persona a la que le fue enviado pueda descifrarlo de la forma
más fácil, conocer los tiempos de ejecución para conocer cuál es el algoritmo más eficiente,
dentro de esta eficiencia equilibrar también la seguridad que te puede proporcionar, ya que por
tardar un poco más pero siendo más robusto y difícil de romper pueda valer más la pena a que
te dé el resultado más rápido.

Santiago Villegas Fernando


El desarrollo de este proyecto me permitió terminar de asimilar algunos conceptos de
cada algoritmo, conceptos que en su momento no terminé de comprender, de los cuales tenía
dudas y preguntas. Aunque ya comprendo mejor los algoritmos, el desarrollo de este proyecto
también me planteó algunas otras dudas, como el comportamiento de los algoritmos con
mensajes extremadamente largos, si los tiempos de ejecución hubieran cambiado si se hubieran
hecho en otro lenguaje de programación o si cambian si se ejecutan en un equipo con diferentes
características. Definitivamente un proyecto satisfactorio para conocer las velocidades de los
algoritmos y determinar cuál es el mejor.

Referencias
● Eijs, H. (5 de 2 de 2022). API documentation. Recuperado el 23 de 4 de 2022, de
pycryptodome: https://www.pycryptodome.org/en/latest/src/api.html
● Individual Contributors. (2021). Welcome to pyca/cryptography.io. Recuperado El 23 de
4 de 2022, de cryptography:
https://cryptography.io/en/latest/hazmat/primitives/asymmetric/ec/?
highlight=ecdsa#key-loading

También podría gustarte