Usar chave privada RSA para gerar chave pública?

394

Eu realmente não entendo este:

de acordo com: http://www.madboa.com/geek/openssl/#key-rsa , você pode gerar uma chave pública a partir de uma chave privada.

openssl genrsa -out mykey.pem 1024
openssl rsa -in mykey.pem -pubout > mykey.pub

Meu pensamento inicial era que eles são gerados em um par juntos. A chave privada RSA contém a soma? ou a chave pública?

c2h2
fonte
11
Para todo mundo usando rsa e openssl e querendo criptografar um arquivo grande como 5 Kbyte. lembre-se de que a chave pública deve ser proporcional ou maior em tamanho ao que você deseja criptografar, caso contrário, você receberá uma "falha de arquivo grande a ser criptografado". Resumo que você gera uma chave privada bastante grande e séria e, a partir disso, cria suas chaves privadas para ter muitos dados com os quais trabalhar. Eu disse a quem eu conheço em aberto sobre a falha, e que eles deveriam fazer um loop por si próprio, caso contrário, você usará muito tempo para descobrir por que ela reclama do tamanho.
Kent Hansen
10
O problema que Kent Hansen descreve deve-se ao uso do RSA diretamente em dados de texto sem formatação, o que nunca deve ser feito por motivos de segurança. Em vez disso, use um esquema de criptografia híbrida bem analisado, como o RSA-KEM ( tools.ietf.org/html/rfc5990#appendix-A ), com um esquema de criptografia simétrica autenticada, como o encrypt-then-HMAC aplicado aos dados.
Daira Hopwood
Isso pode ajudar: jason4zhu.blogspot.jp/2014/10/…
Julgando 28/10
relacionado: serverfault.com/questions/52285/…
David Cary
@ Resposta de SteffenUllrich nesta ligação explica porquê: security.stackexchange.com/questions/172274/...
bearzyj

Respostas:

577
openssl genrsa -out mykey.pem 1024

realmente produzirá um par de chaves público-privado. O par é armazenado no mykey.pemarquivo gerado .

openssl rsa -in mykey.pem -pubout > mykey.pub

extrairá a chave pública e a imprimirá. Aqui está um link para uma página que descreve isso melhor.

EDIT: Verifique a seção de exemplos aqui . Para gerar apenas a parte pública de uma chave privada:

openssl rsa -in key.pem -pubout -out pubkey.pem

Para obter uma chave pública utilizável para fins de SSH, use ssh-keygen :

ssh-keygen -y -f key.pem > key.pub
Raam
fonte
50
é confuso como todos em tutoriais em todos os lugares está dizendo que usando o comando openssl genrsa você irá gerar a chave privada, porque eles estão esquecendo que está a gerar a chave pública também
Jaime Hablutzel
15
@jaime você pode realmente culpá-los? A documentação oficial não diz absolutamente nada sobre uma chave pública. "DESCRIÇÃO: O comando genrsa gera uma chave privada RSA." openssl.org/docs/apps/genrsa.html
Despertar
124
@jaime, é porque não - o genrsa gera apenas a chave privada, a chave pública não é armazenada. No entanto, se você tiver a chave privada, poderá calcular (derivar) a chave pública dela - que é o que o segundo comando acima faz. Calcula, não extrai, a chave pública.
27613 steveayre
13
@steveayre Entendi que as chaves RSA eram simplesmente os dois expoentes ( ee dna literatura comum). Nenhum deles é matematicamente privado ou público; esses são rótulos que são arbitrariamente atribuídos na criação. Eles poderiam facilmente ser atribuídos ao contrário. Gerar um a partir do outro é um problema equivalente. O .pemformato contém um monte de informações, incluindo os dois expoentes e as duas teclas, certo?
Lynks
13
@steveayre está principalmente errado. Os componentes-chave públicos da RSA (n, e) são gerados e incorporados ao arquivo-chave privado da RSA criado com o openssl genrsacomando Um arquivo de chave pública separado não é criado na mesma etapa. Para extrair a chave pública do arquivo de chave privada em um arquivo de chave pública separado, use seu openssl rsa -in private.pem -pubout -out public.pemcomando. Quando você produz uma chave pública dessa maneira, ela é extraída do arquivo de chave privada, não calculada. Veja minha resposta abaixo para mais detalhes.
golem
273

Pessoas que procuram chave pública SSH ...

Se você deseja extrair a chave pública para uso com o OpenSSH, precisará obter a chave pública de maneira um pouco diferente

$ ssh-keygen -y -f mykey.pem > mykey.pub

Esse formato de chave pública é compatível com o OpenSSH. Acrescente a chave pública remote:~/.ssh/authorized_keyse você estará pronto


documentos de SSH-KEYGEN(1)

ssh-keygen -y [-f input_keyfile]  

-y Esta opção lê um arquivo de formato OpenSSH privado e imprime uma chave pública OpenSSH no stdout.

Obrigado
fonte
3
Isso funciona como um encanto! Ele gera um formato que o Github usa! Github não aceita o formato PEM. A resposta anterior sugerida openssl rsa -in key.pem -pubout -out pubkey.pemnão foi aceita, pois evidentemente a saída dessa é uma chave pública no formato pem. Então, recebi o seguinte erro: "A chave é inválida. Ela deve começar com 'ssh-rsa' ou 'ssh-dss'. Verifique se você está copiando a metade pública da chave". No entanto, ssh-keygen -y [-f input_keyfile] gera o formato correto utilizado pelo Github.
Devy
71

Na maioria dos softwares que gera chaves privadas RSA, incluindo openssl, a chave privada é representada como um objeto RSAPrivatekey PKCS # 1 ou alguma variante do mesmo:

A.1.2 Sintaxe da chave privada RSA

Uma chave privada RSA deve ser representada com o tipo ASN.1
RSAPrivateKey:

  RSAPrivateKey ::= SEQUENCE {
      version           Version,
      modulus           INTEGER,  -- n
      publicExponent    INTEGER,  -- e
      privateExponent   INTEGER,  -- d
      prime1            INTEGER,  -- p
      prime2            INTEGER,  -- q
      exponent1         INTEGER,  -- d mod (p-1)
      exponent2         INTEGER,  -- d mod (q-1)
      coefficient       INTEGER,  -- (inverse of q) mod p
      otherPrimeInfos   OtherPrimeInfos OPTIONAL
  }

Como você pode ver, esse formato possui vários campos, incluindo o módulo e o expoente público e, portanto, é um superconjunto estrito das informações em uma chave pública RSA .

Presidente James K. Polk
fonte
Você quer dizer que, dada uma chave privada, é matematicamente viável gerar a chave pública? A força da RSA não é o fato de ser computacionalmente inviável gerar uma chave, dada a outra?
Raam
30
@Raam: Não, o ponto forte da RSA é que é inviável gerar a chave privada do público. Gere a forma pública, o privado é trivial.
Presidente James K. Polk
@GregS, Por quê? Uma chave consiste em um módulo e um expoente. Se o outro expoente puder ser calculado a partir desses dois números, o RSA seria facilmente quebrado. Então, a chave privada OpenSSL contém mais que expoente e módulo?
Calmarius
11
@Calmarius: Quem disse que uma chave consiste em um módulo e expoente? Essa seria a chave privada mínima, mas geralmente a chave privada inclui outros componentes, como os fatores principais. Leia a resposta para obter detalhes.
Presidente James K. Polk
11
@JamesKPolk Isso não é necessariamente verdade. Se o expoente público for grande (ou seja, tiver as mesmas propriedades que o expoente privado), poderá ser impossível reconstruir a chave pública . A maioria das bibliotecas não suporta isso, mas o sistema de criptografia RSA certamente não exige que você reconstrua a chave pública a partir da chave privada.
Maarten Bodewes
34

Minha resposta abaixo é um pouco longa, mas espero que ele forneça alguns detalhes que estão faltando nas respostas anteriores. Vou começar com algumas afirmações relacionadas e, finalmente, responder à pergunta inicial.

Para criptografar algo usando o algoritmo RSA, você precisa de um módulo e um par de expoentes de criptografia (público) (n, e). Essa é a sua chave pública. Para descriptografar algo usando o algoritmo RSA, você precisa de um módulo e um par de expoentes de descriptografia (privado) (n, d). Essa é a sua chave privada.

Para criptografar algo usando a chave pública RSA, você trata seu texto sem formatação como um número e o eleva ao poder do módulo n:

ciphertext = ( plaintext^e ) mod n

Para descriptografar algo usando a chave privada RSA, você trata o texto cifrado como um número e o eleva ao poder do módulo d:

plaintext = ( ciphertext^d ) mod n

Para gerar chave privada (d, n) usando o openssl, você pode usar o seguinte comando:

openssl genrsa -out private.pem 1024

Para gerar chave pública (e, n) a partir da chave privada usando o openssl, você pode usar o seguinte comando:

openssl rsa -in private.pem -out public.pem -pubout

Para dissecar o conteúdo da chave RSA privada private.pem gerada pelo comando openssl acima, execute o seguinte (saída truncada para os rótulos aqui):

openssl rsa -in private.pem -text -noout | less

modulus         - n
privateExponent - d
publicExponent  - e
prime1          - p
prime2          - q
exponent1       - d mod (p-1)
exponent2       - d mod (q-1)
coefficient     - (q^-1) mod p

A chave privada não deve consistir apenas em (n, d) par? Por que existem 6 componentes extras? Ele contém e (expoente público) para que a chave RSA pública possa ser gerada / extraída / derivada da chave RSA privada private.pem. Os demais 5 componentes estão lá para acelerar o processo de descriptografia. Acontece que, ao pré-computar e armazenar esses 5 valores, é possível acelerar a descriptografia do RSA pelo fator 4. A descriptografia funcionará sem esses 5 componentes, mas poderá ser feita mais rapidamente, se você os tiver à mão. O algoritmo de aceleração é baseado no teorema chinês do restante .

Sim, a chave privada RSA private.pem realmente contém todos esses 8 valores; nenhum deles é gerado rapidamente quando você executa o comando anterior. Tente executar os seguintes comandos e compare a saída:

# Convert the key from PEM to DER (binary) format
openssl rsa -in private.pem -outform der -out private.der

# Print private.der private key contents as binary stream
xxd -p private.der

# Now compare the output of the above command with output 
# of the earlier openssl command that outputs private key
# components. If you stare at both outputs long enough
# you should be able to confirm that all components are
# indeed lurking somewhere in the binary stream
openssl rsa -in private.pem -text -noout | less

Essa estrutura da chave privada RSA é recomendada pelo PKCS # 1 v1.5 como uma representação alternativa ( segunda ). O padrão PKCS # 1 v2.0 exclui os expoentes e ed da representação alternativa por completo. O PKCS # 1 v2.1 e v2.2 propõem mudanças adicionais na representação alternativa, incluindo opcionalmente mais componentes relacionados ao CRT.

Para ver o conteúdo da chave public.pem public RSA, execute o seguinte (saída truncada para rótulos aqui):

openssl rsa -in public.pem -text -pubin -noout

Modulus             - n
Exponent (public)   - e

Não há surpresas aqui. É apenas (n, e) par, como prometido.

Agora, finalmente, respondendo à pergunta inicial: Como foi mostrado acima, a chave RSA privada gerada usando o openssl contém componentes das chaves pública e privada e um pouco mais. Quando você gera / extrai / deriva uma chave pública da chave privada, o openssl copia dois desses componentes (e, n) em um arquivo separado que se torna sua chave pública.

golem
fonte
você escreveu "Para gerar chave pública (d, n) a partir da chave privada ...". Não deveria ser "(e, n)"? Obrigado pela ótima resposta!
elactic
Você está comparando a 'sintaxe' (externa) na v1.5 com a semântica nas versões posteriores; verifique 2.0 # 11.1.2 e 2.1 e 2.2 # A.1.2 e você verá n, e, d ainda presentes. (A resposta de como James Polk já observado.)
dave_thompson_085
11
explicação incrível. Obrigado
Francisco Albert
11
Parece que o expoente público eé sempre 65537 0x010001. Provavelmente é um defeito para a escolha do expoente público e é provavelmente por isso que na página de manual e em quase todos os lugares genrsaé explicado como to generate the private key. O público é meio óbvio.
shampoo
Posso calcular o (n, e) apenas a partir de (n, d)?
Flyq 17/01
21

A chave pública não é armazenada no arquivo PEM, como algumas pessoas pensam. A seguinte estrutura DER está presente no arquivo de chave privada:

openssl rsa -text -em mykey.pem

RSAPrivateKey ::= SEQUENCE {
  version           Version,
  modulus           INTEGER,  -- n
  publicExponent    INTEGER,  -- e
  privateExponent   INTEGER,  -- d
  prime1            INTEGER,  -- p
  prime2            INTEGER,  -- q
  exponent1         INTEGER,  -- d mod (p-1)
  exponent2         INTEGER,  -- d mod (q-1)
  coefficient       INTEGER,  -- (inverse of q) mod p
  otherPrimeInfos   OtherPrimeInfos OPTIONAL
}

Portanto, existem dados suficientes para calcular a chave pública (módulo e expoente público), que é o que openssl rsa -in mykey.pem -puboutfaz

Uxio
fonte
Vejo que a chave pública não está armazenada lá, embora derivada como a chave privada, mas também não vejo a chave privada armazenada ?! no entanto, se eu cat o arquivo pem, vejo que diz chave privada e algumas ascii.
Barlop #
2
A chave privada também é derivada, veja o campo privateExponent. Você pode ver os campos usando openssl rsa -text -in mykey.pem
Uxio 8/14
2
A chave pública é realmente armazenada no pem, porque o pem também inclui e ed, ou seja, a chave pública. Ao contrário de algos de log discretos, a chave pública rsa não pode ser calculada apenas com a chave privada (d, n). Ele existe apenas porque as especificações rsa indicam armazená-lo com a chave privada e outras informações.
Michael Chourdakis
11
Sim, esta resposta está com todas as intenções e propósitos ERRADA . O expoente público e o módulo estão lá, então a chave pública está certamente presente. Não há necessidade do expoente público lá, a não ser recuperar facilmente a chave pública sem nenhum cálculo .
Maarten Bodewes
11
@MaartenBodewes: A resposta está correta. O que é citado é retirado do RFC relevante como os valores armazenados para uma chave PRIVATE. O fato de dois dos valores também serem / usados ​​apenas para criptografia de chave pública não altera os dados da chave privada. Aprendi tudo isso nos últimos dois dias, não fazendo perguntas, mas olhando e lendo o padrão relevante. Agora eu entendo tudo sobre ASN.1, DER, PEM e RSA (bem, talvez nem tudo sobre RSA).
AlastairG
8

aqui neste código, primeiro estamos criando a chave RSA que é privada, mas ela também possui um par de sua chave pública. Para obter sua chave pública real, basta fazer isso

openssl rsa -in mykey.pem -pubout > mykey.pub

espero que você o obtenha para obter mais informações, verifique isso

Rdx
fonte
6

Em primeiro lugar, uma rápida recapitulação da geração de chaves RSA.

  1. Escolha aleatoriamente dois números primos prováveis ​​aleatórios do tamanho apropriado (p e q).
  2. Multiplique os dois números primos juntos para produzir o módulo (n).
  3. Escolha um expoente público (e).
  4. Faça algumas contas com os primos e o expoente público para produzir o expoente privado (d).

A chave pública consiste no módulo e no expoente público.

Uma chave privada mínima consistiria no módulo e no expoente privado. Não existe um caminho certo computacionalmente viável para passar de um módulo conhecido e expoente privado para o expoente público correspondente.

Contudo:

  1. Formatos práticos de chave privada quase sempre armazenam mais do que n e d.
  2. Como normalmente não é escolhido aleatoriamente, é usado um dentre alguns valores conhecidos. Se e é um dos valores conhecidos e você sabe d, seria fácil descobrir e por tentativa e erro.

Portanto, na maioria das implementações práticas de RSA, você pode obter a chave pública da chave privada. Seria possível construir um sistema de criptografia baseado em RSA onde isso não fosse possível, mas não é o que está feito.

plugwash
fonte
1
Use the following commands:

1. openssl req -x509 -nodes -days 365 -sha256 -newkey rsa:2048 -keyout mycert.pem -out mycert.pem

Loading 'screen' into random state - done
Generating a 2048 bit RSA private key
.............+++
..................................................................................................................................................................+++
writing new private key to 'mycert.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.

2. If you check there will be a file created by the name : mycert.pem

3. openssl rsa -in mycert.pem -pubout > mykey.txt
writing RSA key

4. If you check the same file location a new public key : mykey.txt will be created.
Ankit Jain
fonte
11
Isso é bobo; não é necessário fazer um esforço extra para criar um certificado inútil quando tudo o que você quer é um par de chaves. Para alguns outros Q em que você deseja um certificado, isso pode ser uma resposta.
David_thompson_085