¡Hola a todos los lectores de Habr! No hace mucho tiempo decidí tratar con algoritmos de cifrado y los principios de la firma electrónica. El tema, creo, es interesante y relevante. En el proceso de estudio, probé varias bibliotecas, pero la biblioteca
PyCrypto es la más conveniente desde mi punto de vista. Ella tiene una excelente documentación, acompañada de ejemplos.
Después de leer el material, aprenderá los siguientes puntos:- ¿Qué es el cifrado?
- ¿Cuál es la diferencia entre cifrado simétrico y asimétrico?
- En cuyo caso, es más eficiente usar el cifrado simétrico y en el cual el cifrado asimétrico;
- ¿Qué es un hash de datos y por qué se usa en el cifrado?
La relevancia del tema está en constante crecimiento. El uso de la criptografía no se ha limitado durante mucho tiempo al cifrado de información. De una forma u otra, usamos algoritmos de encriptación diariamente cuando visitamos sitios a través del protocolo HTTPS, al hacer compras con una tarjeta de crédito y al comunicarnos en mensajería instantánea. En los últimos años, las tecnologías blockchain, que también se basan en la criptografía, han atraído una gran atención.
El propósito de este artículo es presentar al lector los algoritmos de cifrado básicos. Al escribir un artículo, traté de prestar la mayor atención posible al tema de la aplicación práctica. Para la programación, se utilizó Python 3.6. Al escribir el código, traté de dividirlo en partes separadas y comentar todos los puntos clave.
En este artículo, no analicé la firma digital, pero después de comprender el cifrado asimétrico, el significado de esta tecnología quedará claro.
Parcela
Viajemos mentalmente al universo de Star Wars antes de los eventos del Episodio 6, cuando las fuerzas de resistencia se den cuenta del comienzo de la construcción de una nueva Estrella de la Muerte. El comando planea introducir un grupo de inteligencia disfrazado de constructores. La operación es muy peligrosa, la comunicación con la sede será difícil. En el caso de una situación de emergencia, cada miembro del grupo puede enviar y recibir mensajes desde la sede con una frecuencia desprotegida.
El propósito del grupo de reconocimiento es cualquier dato que pueda arrojar luz sobre la configuración, las armas y el propósito de la futura estación. Para almacenar datos, se planea desarrollar equipos y software especiales.
La sede aprobó dos opciones para esta operación:Plan A - Devolución de agentes con fuerzas rebeldes dadas;
Plan B: transmisión remota de planes desde la Estrella de la Muerte utilizando el equipo de la estación.
La transferencia de información será rápida, pero después de la transferencia, lo más probable es que el agente sea calculado y capturado.Usted es un programador en un equipo responsable del desarrollo de software.
Al planificar una operación, se consideran varios escenarios negativos posibles:- El enemigo interceptará la señal, comprenderá su contenido sobre la planificación del ataque y acercará el objeto a las fuerzas leales al Imperio. En este caso, las pérdidas entre la resistencia serán mayores;
- Uno de los espías será atrapado y durante el interrogatorio revelará el plan de operación, lo que puede comprometer las claves de cifrado (hablaremos de ellas a continuación);
- Un espía con datos descargados puede ser interceptado por las fuerzas imperiales, que harán cambios en el contenido, informando mal la resistencia sobre las debilidades de la estación. En este caso, durante el ataque, la flota rebelde será enviada en una dirección falsa y destruida gradualmente;
A partir de estos escenarios se formulan las tareas:- El contenido debe estar encriptado de forma segura y protegido de cambios;
- En caso de pérdida de claves de cifrado o su compromiso, debería ser posible obtener nuevas claves de cifrado de forma remota a una frecuencia que el adversario pueda aprovechar.
Cifrado de información
Solucionemos el problema del cifrado de información:
Una clave de cifrado se utiliza para cifrar y descifrar información. Es la clave que hace que el cifrado sea reversible. Cada agente recibirá una clave de cifrado. Después de descargar los datos, el agente los cifrará y los enviará a la sede de la resistencia.
Descripción del principio de encriptaciónEl método en el que el mensaje se encripta y desencripta usando una sola clave se denomina
encriptación simétrica .

El punto débil del cifrado simétrico es la clave de cifrado, o más bien, su entrega al destinatario. Si la clave se ve comprometida durante la entrega, un tercero puede decodificar fácilmente el mensaje. La fuerza del cifrado simétrico es su velocidad, que permite codificar grandes cantidades de datos.
El cifrado asimétrico utiliza dos claves conectadas entre sí: pública y privada.
El mecanismo de acción es el siguiente:- el destinatario envía la clave ABIERTA al remitente;
- el remitente codifica el mensaje usando la clave pública recibida. Al mismo tiempo, el mensaje ahora puede decodificarse solo con la clave privada;
- Al recibir el mensaje cifrado, el destinatario lo decodifica con la clave CERRADA (que se generó en conjunto con el público).
¡Comencemos en la programación! Para desarrollar el software necesario, utilizaremos la biblioteca de Python llamada
pycrypto . Ella tiene una excelente documentación y presenta todos los algoritmos de cifrado comunes.
Primero, desarrollaremos una función para el cifrado simétrico llamada
Advanced Encryption Standard (AES) . Es uno de los algoritmos de cifrado simétrico más comunes.
from Crypto.Cipher import AES
Verifiquemos el rendimiento del código usando un ejemplo message = """ 120 120 / 120 10 30-5 (2) 4.0 """ key = 'Traveling through hyperspace ain't like dusting crops, farm boy.' encr_message = symmetric_encrypt(message, key, verbose = True) print('\n') print('DECRIPTION') decr_message = symmetric_decrypt(encr_message, key) print(decr_message)
Message was encrypted into: ed10e4c65358bb9e351c801c3b3200b21fa86a24021c317bb5c9d8b3f76bdf9f3a7d26781a22402f0e4f41ca831b6d2da9e1e6878c34c79ddc7959af3ae9fc2ba0cfff1c0180a7e0f637f1aa5b24507d552d5dfe7625e7b81d817b5882b2b19bb95f3988a03c78f850098dfc8e6089863deaa39b887eaea4c1d4ba006edaec90205d54b27ed4ac70ed75cdd01732e1176bf04218beb8ae742ff708a201a9d1cb57dd5f2e70dc3239208d23705f7a3aae3e315c4df6d73c871b66c4995cce5f19738f731cd58755d21ed92612c44197f875cddf3f7aa1d60e435ce1492679b9d60c4b8538f52408f321711ac1d2daa6dbbc33dc655abca10e2f5fd3ff27823995b9dcdb62c0bafc1963ab539ccb466f1c140479df34b0005f578f72fcdd76b17391332037b801f74f733a08 DECRIPTION Success! Encrypted hash is b0dbb35b28fbff258350a50c39282b73e31f408c9da937c81d8d48115b491026 Decrypted hash is b0dbb35b28fbff258350a50c39282b73e31f408c9da937c81d8d48115b491026 120 120 / 120 10 30-5 (2) 4.0
Como puede ver, ciframos con éxito el mensaje utilizando la clave pública.
Ejecute el código varias veces. Verá que cada vez que cambia la parte cifrada. Esto se debe a que al cifrar, utilizamos el modo Cipher FeedBack (AES.MODECFB), en el que los bloques de texto sin formato se mezclan con los bloques de texto cifrado. iv - vector de inicialización (lea más sobre el modo aquí ). Al descifrar el mensaje, vemos que el hash del mensaje descifrado coincide con el hash que agregamos durante el cifrado. Esto significa que el descifrado fue correcto.
¿Qué es un hash?Un hash de documento es simplemente una cadena de caracteres que es exclusiva de cualquier conjunto de datos. Con cualquier cambio de datos, el hash cambia mucho. En otras palabras, un hash es una especie de "huella digital" para cualquier conjunto de datos.

Pero, ¿qué pasa si las claves de cifrado se ven comprometidas por alguna razón? Entonces cualquiera puede descifrar la información.
En este caso, necesitamos cambiar de alguna manera las claves de cifrado de forma remota a una frecuencia que el adversario pueda aprovechar. Asumiremos que ya la están escuchando. Entonces, ¿cómo hacemos esto? Aquí, otro método viene al rescate, llamado cifrado asimétrico (o un sistema criptográfico de clave pública). A diferencia del cifrado simétrico, utiliza dos claves: pública y privada. El mensaje se cifra con la clave pública, después de lo cual solo se puede descifrar con la clave privada. La clave pública de descifrado será inútil. Sin embargo, hay un punto importante: la clave privada ciertamente debe ser del par público generado. La presencia de una clave pública es una de varias propiedades importantes e interesantes del cifrado asimétrico. Es decir, podemos transmitir la clave pública por cualquier canal y no tener miedo de que se use para descifrar el mensaje.
Al mismo tiempo, con respecto a nuestra tarea, hay un matiz: el cifrado asimétrico es adecuado para datos pequeños, por ejemplo, mensajes cortos. Solo podemos adivinar la cantidad de datos obtenidos por inteligencia. Por supuesto, podemos dividir todos los datos recibidos en pequeños fragmentos y codificarlos con una clave privada, pero existe una mejor solución. (El problema se resuelve
aquí ).
SoluciónEl usuario Akela_wolf comentó correctamente que cualquiera puede generar y enviar la clave pública. Hice algunos ajustes al plan.
Será correcto si, antes de enviar agentes, la sede generará varios pares de claves y asignará una clave privada a cada agente. Es mejor generar solo unos pocos pares para que cada agente tenga una clave individual. Esto es necesario para personificar con precisión al propietario de la clave.
Luego, si las claves se ven comprometidas, el centro creará una nueva clave SIMÉTRICA, la codificará a cada agente con claves públicas y la enviará por el canal abierto.
Esquema de solución general
Vieja decisión- El agente generará un par de claves (públicas y privadas) en su lugar, luego enviará la clave pública a las fuerzas rebeldes;
- En la sede de la resistencia crearán una nueva clave para el cifrado SIMÉTRICO;
- La clave simétrica se codifica utilizando la clave pública que envió el agente;
- La clave simétrica cifrada se enviará al agente, que la decodificará utilizando la clave privada.
Presta atención a nuestro programa en el canal abierto:
- El agente envía la llave ABIERTA del par, la llave CERRADA está en su poder;
- La sede de la resistencia envía una clave de cifrado simétrica, cifrada con la clave pública enviada por el agente.
Ni el primer ni el segundo mensaje son de ningún valor en la intercepción.
Escribamos el código:
Veamos cómo se ven las teclas. print(private_key.exportKey(format='PEM').decode()) print('\n') print('#'*65) print('\n') print(public_key.exportKey(format='PEM').decode())
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA4JDLu7Vtvg2yqbH6Y0eJPfoEsOlKzgmOodqhA1CqkEG4OpKi
sGW7ciGP4v37GE6edHBCEy4UNkVQtnpPBjzTHvKd1pO70B84vD5OSrS7uNw2EYkj
d/ZwhrJMrcQKRwPkkM4OiewaaAaK0vPWJIKwlW61DY9X7LfNz7aOKMTbKnm1vdR0
919AV98FUmNoQBgka6nXFGmNbi7D43MtLwxBZIXfFupEiANSvOs+57hgaCho7OWM
GUOjLkG6HBscPhJ2W1H5DU9GjwL24ynTvKifgo1/2ue61MV1Pzh5CVaicJKNaRtg
Pd99gFhBGINsXV2X6Jh/W5nNsCddU4EI0AlO8wIDAQABAoIBAARM4YnjrIlSK9Sy
EtBp40frjMFyhjsx1ahlzmWI2utORt/gRPtJx3AlEmNPZ8qMXt5t8+X4IOz1INmN
uAuviH90N++O/q66mlSIgOlPUrT0ipiFXseCUZ9StMMzGNtJSMw5FfAwNEU/stLd
VoF2ezkxWIg88XsX/fn3Tfub4XKLvu4raJGcJ+Fo2GI9hYEGKnHhSuHvDHekTLlQ
z46O+cIwtehbFGcKesyK3zDD1uP5YLPIWpiqt1TgKjJzRF0l4ZJLk+RT7kU2pGIQ
mosOnr+06WyMIg724yQyAIwtS9X0czKBGUESrtTTb1HCXLeTwnncOTxh6q2z42LF
tn34+DECgYEA6EEp4oTvjfTQfUQPMByuAjF1hpdFHQqRymygiFgoF+Mg3QmL0w8j
/84H/q7s8FSx+3th8MK87bFq4lrry+h/mYwmvF5zZbhxcnl2uaX+KUPgpT6TgvAo
WOv2wc4BSaoo9DrxrZId86vpO2qbopw6gkBsvw47HSoQ+FSqXtZ0p8kCgYEA94Zj
b1ulctUjybiszO93TAjkzx3lU3yL+B1eZiQXtJa3mgG+ka1R/uMfr0NlT+Jzo0My
wHV30YRJDxziCrDol9OgSSU0sXwEcUxUIBLBwXLCp1EmMsYG9PB/x4OTWve35a8F
O+rMxuvWaZeIOfVCfL8UEcWweYaVdWIonJN+ltsCgYEAjeSZ2UlMLZce9RjqioNL
EA31dlfeoqJ9dYUuAn6RaB6cSk51vWlnnfXazo9CNIYaAsFbkcL3t+QHn+jaXEZc
BowocjbmG4Q20zBAB6XRBJbynSIA7yMYE1N9+uOHx+CMisGkO12krOUfZex4zzzR
RhhkF8ly9htoKL9ZIv20YXkCgYBzH3UF6PkVZJ5lhtgP5Nx2Z7iLwBrV7ppnBrnO
BcFkw6iXH3KT7KmzQ82LxWvMcMVZzLpBGyFkOAOG3OchE9DKNKpa+sv8NHMYguip
li+5mneAPFTozoOTznuPvtl9OLO2RuXHTVh6uFub9tdsJW8L+A8MiQagLwE6fDHp
SQxaewKBgQDIyzL1THpW3+AMNrOZuI/d3Em5wpGJiZbDSBRosvsfGm/sHaz4Ik5E
nWnftgktmsAD60eORTTh9/ww/nm7f3q9kzT8Sv1MmqeRXq9VFIOeP/+8SSE/7LzD
izlb5xEtVD8LuY54jHyiOxiZC++TQswMnOKKi0Gx26MDoO7Tx9akVw==
-----END RSA PRIVATE KEY-----
#################################################################
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4JDLu7Vtvg2yqbH6Y0eJ
PfoEsOlKzgmOodqhA1CqkEG4OpKisGW7ciGP4v37GE6edHBCEy4UNkVQtnpPBjzT
HvKd1pO70B84vD5OSrS7uNw2EYkjd/ZwhrJMrcQKRwPkkM4OiewaaAaK0vPWJIKw
lW61DY9X7LfNz7aOKMTbKnm1vdR0919AV98FUmNoQBgka6nXFGmNbi7D43MtLwxB
ZIXfFupEiANSvOs+57hgaCho7OWMGUOjLkG6HBscPhJ2W1H5DU9GjwL24ynTvKif
go1/2ue61MV1Pzh5CVaicJKNaRtgPd99gFhBGINsXV2X6Jh/W5nNsCddU4EI0AlO
8wIDAQAB
-----END PUBLIC KEY-----
Como puede ver, las claves de cifrado asimétrico son largas secuencias de caracteres generadas matemáticamente.
Entonces, generamos las claves. Ahora escribamos una función para codificar datos:
from Crypto.PublicKey import RSA
Pasos de flujo de trabajo- El agente genera un par de claves:
private_key, public_key = generate_keys()
- Envía la llave ABIERTA a la sede;
- En la sede, utilizando la clave pública, codifique la clave para el cifrado simétrico:
new_symmetric_key = 'SOME_KEY_asdfasdfasdfasdfsdfgrtwhetynt' encr_msg = encrypt_message(new_symmetric_key, public_key)
ConclusiónMessage: SOME_KEY_asdfasdfasdfasdfsdfgrtwhetynt was encrypted to
41e940507c96397e3feb4a53390c982633bb1775a52957996a8069bd22063086a0e831bf775a17909276aba0d0478ee6c953837c8ea5d20d40e1c8eb463aaa1bc5c93c71677b1a85e90439c9dbda8a98ce168acb38368155437c66815b84aa2fbdda0eb909e4e6079b4410c720eddd955ed048193bf87f8f9976a17ee32a58a71dfddf3db116343d949d29c25f72c511a440a50a5d4f1e01c37b24a1cb4127e191d3231328b2f120c7dbd0cb5bf19823f0978b8ed17d25952de4b146ef9724fff359eb2af503fdfd72b91525a5503b076ba9aaaeac55af3f8d210c12d579d45dd70362123c0b4b36ef9c2f7705e6f884a25553eb0e11e5077f11fa986d0ff280
- Esta larga secuencia se envía de vuelta al agente;
- El agente descifra el mensaje recibido utilizando la clave privada:
recieved_symmetric_key = decrypt_message(encr_msg, private_key) print('\n') print(f"New symmetric key is: {recieved_symmetric_key}")
Conclusión Success! Encrypted hash is 42ad66445a05ac09e684bb21f9b487d95b9cfa11d02e0b459931321ee02f7c1c Decrypted hash is 42ad66445a05ac09e684bb21f9b487d95b9cfa11d02e0b459931321ee02f7c1c New symmetric key is: SOME_KEY_asdfasdfasdfasdfsdfgrtwhetynt
- Luego, utilizando una nueva clave simétrica, el agente cifra los datos recibidos:
message = """ 120 120 / 120 10 30-5 (2) 4.0 """ encr_message = symmetric_encrypt(message, recieved_symmetric_key, verbose = True)
Conclusión Message was encrypted into:
- La sede descifra:
print('DECRIPTION') decr_message = symmetric_decrypt(encr_message, new_symmetric_key) print(decr_message)
Conclusión DECRIPTION Success! Encrypted hash is b0dbb35b28fbff258350a50c39282b73e31f408c9da937c81d8d48115b491026 Decrypted hash is b0dbb35b28fbff258350a50c39282b73e31f408c9da937c81d8d48115b491026 120 120 / 120 10 30-5 (2) 4.0
Voila!En este ejemplo abstracto, vimos el trabajo de algoritmos de cifrado comunes. El cifrado simétrico y asimétrico, así como el hash, se utilizan
en el trabajo de la web ,
firma electrónica ,
blockchain y criptomonedas . Espero que el material haya sido útil para comprender el funcionamiento de estas tecnologías.
Epílogo
Como resultado, la inteligencia rebelde logró obtener información precisa sobre la vulnerabilidad de la estación y el camino hacia ella, la presencia del Emperador para la inspección, la presencia de un escudo de energía y su fuente en Endor. El imperio vio a los espías, les informó mal sobre la capacidad de combate de la estación. La estación también fue asignada al satélite de Endor, desde donde estaba protegida por un escudo.
Pero sabemos cómo terminó todo;)