Como uma chave pública verifica uma assinatura?

173

Estou tentando entender melhor como funcionam as chaves públicas / privadas. Entendo que um remetente pode adicionar uma assinatura digital a um documento usando sua chave privada para obter essencialmente um hash do documento, mas o que não entendo é como a chave pública pode ser usada para verificar essa assinatura.

Meu entendimento era que as chaves públicas criptografam, as chaves privadas descriptografam ... alguém pode me ajudar a entender?

jcampos8782
fonte
3
Boa pergunta. :)
Suraj Jain
Eu não queria adicionar isso como resposta e arriscar as chamas que se seguiram, mas se você usar a palavra "como" realmente significa "como verifico uma assinatura", uma possibilidade é fazer o download do gpg4win. Depois de instalado, você pode clicar com o botão direito do mouse em um arquivo e verificá-lo. É um conjunto de produtos que se integram ao shell do Windows. Um desses utilitários é o Kleopatra, que procurará certificados online para fazer a validação.
Newclique

Respostas:

210

Sua compreensão de "criptografia de chaves públicas, descriptografia de chaves privadas" está correta ... para dados / mensagem ENCRYPTION. Para assinaturas digitais, é o contrário. Com uma assinatura digital, você está tentando provar que o documento assinado por você veio de você. Para fazer isso, você precisa usar algo que apenas você tem: sua chave privada.

Uma assinatura digital em sua descrição mais simples é um hash (SHA1, MD5 etc.) dos dados (arquivo, mensagem etc.) que são subsequentemente criptografados com a chave privada do assinante. Como isso é algo que apenas o assinante tem (ou deveria ter) e é daí que a confiança vem. TODOS têm (ou deveriam ter) acesso à chave pública do assinante.

Portanto, para validar uma assinatura digital, o destinatário

  1. Calcula um hash dos mesmos dados (arquivo, mensagem etc.),
  2. Descriptografa a assinatura digital usando a chave PUBLIC do remetente e
  3. Compara os 2 valores de hash.

Se eles corresponderem, a assinatura é considerada válida. Se eles não corresponderem, significa que uma chave diferente foi usada para assiná-lo ou que os dados foram alterados (intencionalmente ou não).

Espero que ajude!

Homem sombra
fonte
13
Meu entendimento era que as chaves não eram simétricas ... ou seja, objetos criptografados com uma chave pública podem ser descriptografados pela chave privada, mas que esse relacionamento não funcionou inversamente ... mais especificamente, não achei objetos criptografado com a chave privada pode ser descriptografado pela chave pública. Se esse é realmente o caso, isso definitivamente responde à minha pergunta.
precisa saber é o seguinte
63
As teclas funcionam inversamente entre si. Criptografou algo com sua chave pública? Descriptografá-lo com sua chave privada. Por outro lado, se você criptografou algo com sua chave privada, descriptografou-o com o seu público. Essa é a natureza da criptografia assimétrica.
Shadowman
20
Simétrico significa apenas que a mesma chave é usada para criptografar / descriptografar. Assimétrico significa que uma chave criptografa e uma chave diferente descriptografa (e que o inverso também é verdadeiro).
gtrig
8
@Jodimoro, tecnicamente uma mensagem NÃO é "secreta" se for criptografada com uma chave privada. Se for criptografada com uma chave privada, qualquer pessoa com a chave "pública" disponível publicamente pode descriptografar a mensagem.
RayLoveless
4
@Jodimoro A única razão pela qual o hash é criptografado com uma chave privada em uma assinatura é garantir que o hash não seja alterado ... não garantir que seja "secreto".
RayLoveless
72

As teclas funcionam inversamente:

A chave pública criptografa, a chave privada descriptografa (criptografa):

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

Criptografia de chave privada, descriptografia de chave pública (assinatura):

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

Abaixo está um exemplo de script para testar todo esse fluxo 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 gera o seguinte:

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
fonte
2
Obrigado por adicionar o script - definitivamente ajudou a esclarecer as coisas.
Pat
Muito obrigado, é sempre mais fácil para mim entender com ecample
Simon
16

A chave pública criptografa e somente a chave privada pode descriptografá-la, e o inverso é verdadeiro. Ambos criptografam em hashes diferentes, mas cada chave pode descriptografar a criptografia da outra.

Existem algumas maneiras diferentes de verificar se uma mensagem veio de algum remetente esperado. Por exemplo:

O remetente envia:

  1. A mensagem

  2. O hash da mensagem criptografada com sua chave privada

O receptor:

  1. Descriptografa a assinatura (2) com a chave pública para obter uma mensagem, supostamente a mesma mensagem que (1), mas ainda não sabemos. Agora temos duas mensagens que precisamos verificar são idênticas. Para fazer isso, criptografá-los com nossa chave pública e comparar os dois hashes. Então vamos ....
  2. Criptografe a mensagem original (1) com a chave pública para obter um hash
  3. Criptografe a mensagem descriptografada (3) para obter um segundo hash e compare com (4) para verificar se eles são idênticos.

Se não forem idênticas, significa que a mensagem foi adulterada ou assinada com outra chave e não a que pensávamos ...

Outro exemplo seria o remetente usar um hash comum que o destinatário talvez também saiba usar. Por exemplo:

O remetente envia:

  1. Uma mensagem
  2. Pega um hash conhecido da mensagem e, em seguida, criptografa o hash com a chave privada

O receptor:

  1. Descriptografa (2) e obtém um valor de hash
  2. Coloca em hash a mensagem (1) com o mesmo hash usado pelo remetente
  3. Compara os dois hashes para garantir que eles correspondam

Isso novamente garante que a mensagem não foi violada e é do remetente esperado.

wueb
fonte
6

Se eu tivesse que refazer sua pergunta de como eu a entendo, você está fazendo o seguinte:

Se a criptografia de chave pública garante que uma chave pública possa ser derivada de uma chave privada, mas uma chave privada não pode ser derivada de uma chave pública, você pode se perguntar: como uma chave pública pode descriptografar uma mensagem assinada com uma chave privada sem o remetente expondo a chave privada na mensagem assinada ao destinatário? (releia isso algumas vezes até que faça sentido)

Outras respostas já explicou como assimétricas meio de criptografia que você pode tanto :

  1. Criptografar com chave pública, descriptografar com chave privada correspondente (pseudocódigo abaixo)
var msg = 'secret message';

var encryptedMessage = encrypt(pub_key, msg);

var decryptedMessage = decrypt(priv_key, encryptedMessage);

print(msg == decryptedMessage == 'secret message'); // True
  1. Criptografar com chave privada, descriptografar com chave pública correspondente (pseudocódigo abaixo)
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

Nós sabemos que tanto o exemplo # 1 e # 2 trabalho. O exemplo 1 faz sentido intuitivo, enquanto o exemplo 2 implora a pergunta original .

Acontece que a criptografia de curva elíptica (também chamada de "multiplicação de curva elíptica") é a resposta para a pergunta original. A criptografia de curva elíptica é a relação matemática que possibilita as seguintes condições:

  1. Uma chave pública pode ser matematicamente gerada a partir de uma chave privada
  2. Uma chave privada não pode ser matematicamente gerada a partir de uma chave pública (por exemplo, "função trapdoor")
  3. Uma chave privada pode ser verificada por uma chave pública

Para a maioria, as condições 1 e 2 fazem sentido, mas e a 3?

Você tem duas opções aqui:

  1. Você pode descer por uma toca de coelho e passar horas e horas aprendendo como a criptografia de curva elíptica funciona ( aqui é um ótimo ponto de partida ) ... OU ...
  2. Você pode aceitar as propriedades acima - assim como aceita as 3 leis do movimento de Newton sem precisar derivá- las.

Em conclusão, um par de chaves público / privado é criado usando criptografia de curva elíptica, que por natureza cria uma chave pública e privada que são matematicamente vinculadas em ambas as direções, mas não derivadas matematicamente em ambas as direções . É isso que possibilita o uso da chave pública de alguém para verificar se eles assinaram uma mensagem específica, sem que eles exponham sua chave privada para você.

Zach Gollwitzer
fonte
Suas três condições explicam tudo. Acabei de ler este termo 'curva elíptica' e fiquei tipo wtf
Simon
5

Pensei em fornecer uma explicação suplementar para quem procura algo mais intuitivamente revelador.

Uma grande parte dessa confusão surge do nome de 'chaves públicas' e 'chaves privadas', como tal, porque o modo como essas coisas realmente funcionam está diretamente em desacordo com o modo como uma 'chave' é entendida.

Veja a criptografia, por exemplo. Pode-se pensar assim:

  • As partes que desejam ler as mensagens secretas mantêm uma chave oculta (ou seja, uma chave privada)
  • As partes que desejam poder enviar mensagens secretas têm a capacidade de obter um bloqueio desbloqueado (ou seja, um bloqueio público)
  • Em seguida, enviar uma mensagem secreta é tão fácil quanto bloqueá-lo com um bloqueio desbloqueado, mas desbloqueá-lo depois só pode ser feito com uma das chaves ocultas.

Isso permite que mensagens secretas sejam enviadas entre as partes, mas do ponto de vista intuitivo aqui, 'bloqueio público' é um nome mais adequado do que 'chave pública'.

No entanto, para enviar assinaturas digitais, as funções são um pouco invertidas:

  • A parte que deseja assinar mensagens é a única com acesso aos bloqueios desbloqueados (ou seja, um bloqueio privado)
  • As partes que desejam verificar a assinatura têm a capacidade de obter uma chave (ou seja, uma chave pública)
  • Então, o que o assinante faz é criar duas mensagens idênticas: aquela que qualquer um pode ler e outra para acompanhá-lo, mas que trava com um de seus bloqueios particulares.
  • Então, quando o destinatário receber a mensagem, eles poderão lê-la e, em seguida, usar a chave pública para desbloquear a mensagem bloqueada e comparar as duas mensagens. Se as mensagens forem as mesmas, eles saberão que:

    1. A mensagem desbloqueada não foi adulterada durante a viagem e,

    2. A mensagem deve ter sido da pessoa que possui o bloqueio correspondente à sua chave pública.

  • E, finalmente, todo esse sistema funciona apenas se alguém que deseja validar a assinatura de um assinante tem um local autorizado para obter a chave correspondente aos bloqueios do assinante. Caso contrário, qualquer um pode dizer "Ei, aqui está a chave para o bloqueio privado do tipo" e assim por diante ", enviar uma mensagem fingindo ser eles, mas bloqueá-la com o bloqueio privado, você executa todas as etapas acima e acredita que a mensagem deve realmente ser da pessoa que você pensou, mas você está enganado porque se enganou quanto ao verdadeiro proprietário de uma chave pública.

Desde que haja uma fonte confiável para recuperar a chave pública de um assinante, você saberá quem é o proprietário legítimo de uma chave pública e poderá validar sua assinatura.

sapato
fonte
4
Alterar 'chave' para 'bloqueio desbloqueado' apenas aumenta a confusão.
Marquês de Lorne #
@EJP Não mudo a chave para 'trava desbloqueada'. Foi alterado para 'bloquear'. 'Bloqueado desbloqueado' é usado apenas para a finalidade de expressar o uso do item. Independentemente disso, é sua opinião e, se você tiver alguma experiência de longo prazo na comunidade de criptografia, é provável que seja extremamente tendenciosa, porque os termos existentes são como você aprendeu a entender a tecnologia. Por que você não deixa as pessoas que estão começando a determinar se a analogia é ou não útil?
sapato
1
Eu acho que a analogia com fechaduras e chaves é muito boa para fornecer uma primeira compreensão desse assunto. Depois de visualizar os bloqueios e as chaves, eles podem ser trocados com números inteiros diferentes montados em chaves rsa (ou outro tipo de).
Andreas Lundgren
Pessoalmente, acho que esse insight é o melhor que li até agora. E, definitivamente, veja como a adição de bloqueio em vez de chave para privado / público torna todo o sistema intuitivamente auto-explicativo para novos usuários regulares. Enquanto no momento não é de todo. Somos desenvolvedores experientes (apenas sem contato direto com criptografia até agora) e discutimos sobre o objetivo de público / privado por algum tempo. Eu estava dizendo que privada é usada para criptografar, enquanto ele estava dizendo que pública é usada para criptografar: D
jayarjo
0

Para sua pergunta - eu estava analisando a implementação do RSA. E obteve mais clareza sobre como uma chave pública é usada para verificar a assinatura usando uma chave privada. Sem dúvida, a chave privada não está exposta. Aqui está como...

O truque aqui é ocultar a chave privada dentro de uma função. Nesse caso,(p-1)*(q-1).

Considere p como a chave privada ee como a chave pública. 'p' é encapsulado em outra função para torná-lo oculto.

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

Dados enviados = [criptografado (hash), mensagem] = [m ^ d, mensagem]; onde m é a mensagem Suponha 'Dados enviados' = y Para verificar a integridade, encontramos y ^ e para obter m. Desde então m ^(d*e) = m ^1 = m.

Espero que isto ajude! :)

George John
fonte