¿Cómo una clave pública verifica una firma?

173

Estoy tratando de entender mejor cómo funcionan las claves públicas / privadas. Entiendo que un remitente puede agregar una firma digital a un documento usando su clave privada para obtener esencialmente un hash del documento, pero lo que no entiendo es cómo se puede usar la clave pública para verificar esa firma.

Entendí que las claves públicas cifran, las claves privadas descifran ... ¿alguien puede ayudarme a entender?

jcampos8782
fuente
3
Buena pregunta. :)
Suraj Jain
No quería agregar esto como respuesta y arriesgarme con las llamas que siguen, pero si usas la palabra "cómo" realmente significa "cómo verifico una firma", entonces una posibilidad es descargar gpg4win. Una vez instalado, puede hacer clic derecho en un archivo y verificarlo. Es un conjunto de productos que se integran en el shell de Windows. Una de esas utilidades es Kleopatra, que buscará certificados en línea para hacer la validación.
Newclique

Respuestas:

210

Su comprensión de "cifrado de claves públicas, descifrado de claves privadas" es correcta ... para Cifrado de datos / mensajes. Para las firmas digitales, es al revés. Con una firma digital, está intentando demostrar que el documento firmado por usted proviene de usted. Para hacer eso, debe usar algo que solo USTED tiene: su clave privada.

Una firma digital en su descripción más simple es un hash (SHA1, MD5, etc.) de los datos (archivo, mensaje, etc.) que posteriormente se encripta con la clave privada del firmante. Como eso es algo que solo el firmante tiene (o debería tener), de ahí proviene la confianza. TODOS tienen (o deberían tener) acceso a la clave pública del firmante.

Entonces, para validar una firma digital, el destinatario

  1. Calcula un hash de los mismos datos (archivo, mensaje, etc.),
  2. Descifra la firma digital usando la clave PUBLIC del remitente, y
  3. Compara los 2 valores hash.

Si coinciden, la firma se considera válida. Si no coinciden, significa que se usó una clave diferente para firmarlo o que los datos han sido alterados (ya sea intencionalmente o no).

¡Espero que ayude!

Hombre de la sombra
fuente
13
Comprendí que las claves no eran simétricas ... es decir, los objetos cifrados con una clave pública pueden ser descifrados por la clave privada, pero que esta relación no funcionaba a la inversa ... más específicamente, no pensé que los objetos cifrado con la clave privada podría ser descifrado por la clave pública. Si ese es el caso, entonces esto definitivamente responde a mi pregunta.
jcampos8782
63
Las teclas funcionan inversamente entre sí. Cifrado algo con su clave pública? Descifrarlo con su clave privada. Por el contrario, si cifró algo con su clave privada, lo descifrará con su público. Tal es la naturaleza de la criptografía asimétrica.
Shadowman
20
Simétrico solo significa que se usa la misma clave para cifrar / descifrar. Asimétrico significa que una clave se cifra y otra clave se descifra (y que lo contrario también es cierto).
gtrig
8
@Jodimoro, técnicamente un mensaje NO es "secreto" si está encriptado con una clave privada. Si está cifrado con una clave privada, cualquier persona con la clave "pública" disponible públicamente puede descifrar el mensaje.
RayLoveless
44
@Jodimoro La única razón por la que el hash está encriptado con una clave privada en una firma es para garantizar que el hash no se cambie ... no para garantizar que sea "secreto".
RayLoveless
72

Las teclas funcionan a la inversa:

Cifrados de clave pública, descifrados de clave privada (cifrado):

openssl rsautl -encrypt -inkey public.pem -pubin -in message.txt -out message.ssl
openssl rsautl -decrypt -inkey private.pem       -in message.ssl -out message.txt

Cifrados de clave privada, descifrados de clave pública (firma):

openssl rsautl -sign -inkey private.pem       -in message.txt -out message.ssl
openssl rsautl       -inkey public.pem -pubin -in message.ssl -out message.txt

A continuación se muestra un script de ejemplo para probar todo este flujo openssl.

#!/bin/sh
# Create message to be encrypted
echo "Creating message file"
echo "---------------------"
echo "My secret message" > message.txt
echo "done\n"

# Create asymmetric keypair
echo "Creating asymmetric key pair"
echo "----------------------------"
openssl genrsa -out private.pem 1024
openssl rsa -in private.pem -out public.pem -pubout
echo "done\n"

# Encrypt with public & decrypt with private
echo "Public key encrypts and private key decrypts"
echo "--------------------------------------------"
openssl rsautl -encrypt -inkey public.pem -pubin -in message.txt         -out message_enc_pub.ssl
openssl rsautl -decrypt -inkey private.pem       -in message_enc_pub.ssl -out message_pub.txt
xxd message_enc_pub.ssl # Print the binary contents of the encrypted message
cat message_pub.txt # Print the decrypted message
echo "done\n"

# Encrypt with private & decrypt with public
echo "Private key encrypts and public key decrypts"
echo "--------------------------------------------"
openssl rsautl -sign    -inkey private.pem -in message.txt          -out message_enc_priv.ssl
openssl rsautl -inkey public.pem -pubin    -in message_enc_priv.ssl -out message_priv.txt
xxd message_enc_priv.ssl
cat message_priv.txt
echo "done\n"

Este script genera lo siguiente:

Creating message file
---------------------
done

Creating asymmetric key pair
----------------------------
Generating RSA private key, 1024 bit long modulus
...........++++++
....++++++
e is 65537 (0x10001)
writing RSA key
done

Public key encrypts and private key decrypts
--------------------------------------------
00000000: 31c0 f70d 7ed2 088d 9675 801c fb9b 4f95  1...~....u....O.
00000010: c936 8cd0 0cc4 9159 33c4 9625 d752 5b77  .6.....Y3..%.R[w
00000020: 5bfc 988d 19fe d790 b633 191f 50cf 1bf7  [........3..P...
00000030: 34c0 7788 efa2 4967 848f 99e2 a442 91b9  4.w...Ig.....B..
00000040: 5fc7 6c79 40ea d0bc 6cd4 3c9a 488e 9913  [email protected].<.H...
00000050: 387f f7d6 b8e6 5eba 0771 371c c4f0 8c7f  8.....^..q7.....
00000060: 8c87 39a9 0c4c 22ab 13ed c117 c718 92e6  ..9..L".........
00000070: 3d5b 8534 7187 cc2d 2f94 0743 1fcb d890  =[.4q..-/..C....
My secret message
done

Private key encrypts and public key decrypts
--------------------------------------------
00000000: 6955 cdd0 66e4 3696 76e1 a328 ac67 4ca3  iU..f.6.v..(.gL.
00000010: d6bb 5896 b6fe 68f1 55f1 437a 831c fee9  ..X...h.U.Cz....
00000020: 133a a7e9 005b 3fc5 88f7 5210 cdbb 2cba  .:...[?...R...,.
00000030: 29f1 d52d 3131 a88b 78e5 333e 90cf 3531  )..-11..x.3>..51
00000040: 08c3 3df8 b76e 41f2 a84a c7fb 0c5b c3b2  ..=..nA..J...[..
00000050: 9d3b ed4a b6ad 89bc 9ebc 9154 da48 6f2d  .;.J.......T.Ho-
00000060: 5d8e b686 635f b6a4 8774 a621 5558 7172  ]...c_...t.!UXqr
00000070: fbd3 0c35 df0f 6a16 aa84 f5da 5d5e 5336  ...5..j.....]^S6
My secret message
done
Jaakko
fuente
2
Gracias por agregar el script, definitivamente ayudó a aclarar las cosas.
Pat
Muchas gracias, siempre es más fácil para mí entender con ecample
Simon
16

La clave pública cifra y solo la clave privada puede descifrarla, y lo contrario es cierto. Ambos encriptan a diferentes hashes pero cada clave puede desencriptar el encriptado del otro.

Hay algunas formas diferentes de verificar que un mensaje proviene de un remitente esperado. Por ejemplo:

El remitente envía:

  1. El mensaje

  2. El hash del mensaje cifrado con su clave privada

El receptor:

  1. Descifra la firma (2) con la clave pública para obtener un mensaje, supuestamente el mismo mensaje que (1) pero aún no lo sabemos. Ahora tenemos dos mensajes que debemos verificar que sean idénticos. Para hacer esto, los cifraremos con nuestra clave pública y compararemos los dos valores hash. Entonces lo haremos ...
  2. Cifre el mensaje original (1) con la clave pública para obtener un hash
  3. Cifre el mensaje descifrado (3) para obtener un segundo hash y compárelo con (4) para verificar que sean idénticos.

Si no son idénticos, significa que el mensaje fue manipulado o que fue firmado con alguna otra clave y no con la que pensamos ...

Otro ejemplo sería que el remitente use un hash común que el receptor también pueda usar. Por ejemplo:

El remitente envía:

  1. Un mensaje
  2. Toma un hash conocido del mensaje, luego encripta el hash con la clave privada

El receptor:

  1. Descifra (2) y obtiene un valor hash
  2. Hashes el mensaje (1) con el mismo hash usado por el remitente
  3. Compara los dos hash para asegurarse de que coinciden

Esto nuevamente asegura que el mensaje no fue manipulado y que es del remitente esperado.

wueb
fuente
6

Si tuviera que reformular su pregunta de la forma en que la entiendo, está preguntando lo siguiente:

Si la criptografía de clave pública asegura que una clave pública se puede derivar de una clave privada, pero una clave privada no se puede derivar de una clave pública, entonces podría preguntarse, ¿cómo puede una clave pública descifrar un mensaje firmado con una clave privada sin el remitente? exponiendo la clave privada dentro del mensaje firmado al destinatario? (vuelva a leer eso algunas veces hasta que tenga sentido)

Otras respuestas ya han explicado cómo asimétricas medios de criptografía que pueda ya sea :

  1. Cifrar con clave pública, descifrar con clave privada correspondiente (pseudocódigo a continuación)
var msg = 'secret message';

var encryptedMessage = encrypt(pub_key, msg);

var decryptedMessage = decrypt(priv_key, encryptedMessage);

print(msg == decryptedMessage == 'secret message'); // True
  1. Cifrar con clave privada, descifrar con clave pública correspondiente (pseudocódigo a continuación)
var msg = 'secret message';

var encryptedMessage = encrypt(priv_key, msg);

var decryptedMessage = decrypt(pub_key, encryptedMessage); // HOW DOES THIS WORK???

print(msg == decryptedMessage == 'secret message'); // True

Nosotros sabemos que tanto el ejemplo # 1 y # 2 de trabajo. El ejemplo # 1 tiene sentido intuitivo, mientras que el ejemplo # 2 plantea la pregunta original .

Resulta que la criptografía de curva elíptica (también llamada "multiplicación de curva elíptica") es la respuesta a la pregunta original. La criptografía de curva elíptica es la relación matemática que hace posibles las siguientes condiciones:

  1. Una clave pública se puede generar matemáticamente a partir de una clave privada
  2. Una clave privada no se puede generar matemáticamente a partir de una clave pública (es decir, "función de puerta trampa")
  3. Una clave privada puede ser verificada por una clave pública

Para la mayoría, las condiciones n. ° 1 y n. ° 2 tienen sentido, pero ¿qué pasa con el n. ° 3?

Tu tienes dos opciones aquí:

  1. Puede bajar por una madriguera de conejo y pasar horas y horas aprendiendo cómo funciona la criptografía de curva elíptica ( aquí hay un gran punto de partida ) ... O ...
  2. Puede aceptar las propiedades anteriores, al igual que acepta las 3 leyes de movimiento de Newton sin necesidad de derivarlas usted mismo.

En conclusión, se crea un par de claves público / privado utilizando criptografía de curva elíptica, que por naturaleza, crea una clave pública y privada que están vinculadas matemáticamente en ambas direcciones, pero no derivadas matemáticamente en ambas direcciones . Esto es lo que le permite utilizar la clave pública de alguien para verificar que firmó un mensaje específico, sin que exponga su clave privada a usted.

Zach Gollwitzer
fuente
Sus 3 condiciones lo explican todo. Acabo de leer este término 'curva elíptica' y estaba como wtf
Simon
5

Pensé que proporcionaría una explicación suplementaria para cualquiera que busque algo más intuitivamente revelador.

Una gran parte de esta confusión surge de nombrar 'claves públicas' y 'claves privadas' como tales porque cómo funcionan realmente estas cosas está directamente en desacuerdo con cómo se entiende que es una 'clave'.

Tome encriptación por ejemplo. Se podría pensar que funciona así:

  • Las partes que desean poder leer los mensajes secretos mantienen una clave oculta (es decir, una clave privada)
  • Las partes que desean poder enviar mensajes secretos tienen la capacidad de obtener un bloqueo desbloqueado (es decir, un bloqueo público)
  • Luego, enviar un mensaje secreto es tan fácil como bloquearlo con un bloqueo desbloqueado, pero desbloquearlo después solo se puede hacer con una de las teclas ocultas.

Esto permite que se envíen mensajes secretos entre las partes, pero desde un punto de vista intuitivo aquí, 'bloqueo público' es un nombre más adecuado que 'clave pública'.

Sin embargo, para enviar firmas digitales, los roles están algo invertidos:

  • La parte que desea firmar mensajes es la única con acceso a las cerraduras desbloqueadas (es decir, una cerradura privada)
  • Las partes que desean verificar la firma tienen la capacidad de obtener una clave (es decir, una clave pública)
  • Entonces, lo que hace el firmante es crear dos mensajes idénticos: el que cualquiera puede leer y el que lo acompaña, pero que bloquean con una de sus cerraduras privadas.
  • Luego, cuando el receptor recibe el mensaje, puede leerlo y luego usar la clave pública para desbloquear el mensaje bloqueado y comparar los dos mensajes. Si los mensajes son iguales, entonces saben que:

    1. El mensaje desbloqueado no fue alterado durante el viaje y,

    2. El mensaje debe haber sido de la persona que tiene el bloqueo correspondiente a su clave pública.

  • Y finalmente, todo este sistema solo funciona si alguien que quiere validar la firma de un firmante tiene un lugar autorizado para obtener la clave correspondiente para las cerraduras del firmante. De lo contrario, cualquiera puede decir "Oye, aquí está la clave del bloqueo privado de tal y tal", enviarte un mensaje fingiendo ser ellos pero bloquearlo con su bloqueo privado, realizas todos los pasos anteriores y crees que el mensaje debe ser realmente de la persona que pensabas, pero te engañas porque te engañaste en cuanto al verdadero propietario de una clave pública.

Siempre que haya una fuente confiable para recuperar la clave pública de un firmante, sabrá quién es el propietario legítimo de una clave pública y podrá validar su firma.

zapato
fuente
44
Cambiar 'clave' a 'bloqueo desbloqueado' solo aumenta la confusión.
Marqués de Lorne
@EJP No cambio la clave a 'bloqueo desbloqueado'. Se cambió a 'bloquear'. 'Desbloqueado bloqueado' solo se utiliza con el fin de expresar el uso del elemento. En lo que respecta, esa es su opinión, y si tiene alguna experiencia a largo plazo en la comunidad criptográfica, es probable que sea extremadamente parcial porque los términos existentes son cómo ha llegado a comprender la tecnología. ¿Por qué no dejas que las personas que recién comienzan determinen si la analogía es útil o no?
zapato
1
Creo que la analogía con cerraduras y llaves es bastante buena para proporcionar una primera comprensión de este asunto. Una vez que visualiza las cerraduras y las llaves, se pueden intercambiar diferentes enteros que se ensamblan en llaves rsa (u otro tipo de).
Andreas Lundgren
Personalmente, creo que esta idea es la mejor, he leído hasta ahora. Y definitivamente vea cómo agregar cerradura en lugar de clave a privado / público hace que todo el sistema se explique intuitivamente para los recién llegados habituales. Mientras que en este momento no lo es en absoluto. Somos desarrolladores experimentados (solo que hasta ahora no teníamos contacto directo con la criptografía) y discutimos sobre el propósito de lo público / privado por algún tiempo. Estaba diciendo que lo privado se usa para encriptar, mientras él decía que lo público se usa para encriptar: D
jayarjo
0

A su pregunta, estaba mirando la implementación de RSA. Y obtuve más claridad sobre la forma en que se utiliza una clave pública para verificar la firma utilizando una clave privada. Sin lugar a dudas, la clave privada no está expuesta. Aquí es cómo...

El truco aquí es ocultar la clave privada dentro de una función. En este caso,(p-1)*(q-1).

Considere p como la clave privada y e como la clave pública. 'p' está encapsulado dentro de otra función para ocultarlo.

E.g., `d = (p-1)(q-1); d * e = 1` (d is the inverse of e - public key)

Datos enviados = [cifrado (hash), mensaje] = [m ^ d, mensaje]; donde m es el mensaje Suponga 'Datos enviados' = y Para verificar la integridad, encontramos y ^ e para obtener m. Desde m ^(d*e) = m ^1 = m.

¡Espero que esto ayude! :)

George John
fuente