Cifrar / decifrar RSA

Gere pares de chaves RSA no navegador, cifre e decifre com RSA-OAEP, assine com RSA-PSS ou PKCS#1 v1.5, e converta chaves entre os formatos PEM SPKI, PKCS#8 e PKCS#1. Tudo corre localmente com o motor WebCrypto — nenhuma chave ou mensagem sai desta página.
Para que serve o RSA: mensagens pequenas e assinaturas, não dados volumosos. O RSA cifra no máximo k−2·hashLen−2 bytes por chamada (190 bytes para uma chave de 2048 bits com SHA-256) e é ~1000× mais lento do que o AES. Sistemas reais usam cifragem híbrida: o RSA envolve uma chave AES aleatória, o AES cifra os dados (veja a ferramenta AES). Esta página existe para aprendizagem, testes e verificações de interoperabilidade.
Tamanho do módulo:
Hash: Rótulo:
A cifragem PKCS#1 v1.5 não está implementada de propósito: não tem integridade do texto cifrado e cai a ataques de oráculo de preenchimento (Bleichenbacher). O OAEP é o único modo de cifragem que um desenho novo deve usar.
Esquema: Hash:
Esquema: Hash:
Quanto pode transportar uma chamada RSA? Limite de mensagem OAEP = bytes da chave − 2×bytes do hash − 2:
MóduloSHA-256SHA-384SHA-512
1024 bits62 bytes30 bytes0 bytes
2048 bits190 bytes126 bytes62 bytes
3072 bits318 bytes254 bytes190 bytes
4096 bits446 bytes382 bytes318 bytes
As assinaturas não têm limite de mensagem — a mensagem é primeiro submetida a hash; a própria assinatura tem sempre exatamente o tamanho da chave (256 bytes para 2048 bits).
Força e tempo de vida da chave (NIST SP 800-57 Parte 1 Rev. 5): o 1024 bits deixou de ser permitido para uso novo após 2013; 2048 bits é o mínimo atual e continua aceitável até 2030; 3072 bits e acima são a escolha confortável para 2031+. O 8192 bits funciona aqui, mas a geração pode demorar um minuto ou mais no navegador e compra uma segurança que ninguém precisa atualmente — prefira 3072/4096.
Interoperabilidade com OpenSSL — os PEM que esta página produz fazem ciclos na linha de comandos:
openssl pkeyutl -encrypt -pubin -inkey pub.pem -pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256 -pkeyopt rsa_mgf1_md:sha256
openssl pkeyutl -decrypt -inkey priv.pem -pkeyopt rsa_padding_mode:oaep ...
openssl dgst -sha256 -sign priv.pem -out msg.sig msg.txt (PKCS#1 v1.5)  /  openssl dgst -sha256 -verify pub.pem -signature msg.sig msg.txt
PSS: acrescente -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:32 às duas chamadas de dgst. Conversão de formato de chave: openssl rsa -in key.pem -RSAPublicKey -out pubkey.pem faz SPKI ↔ PKCS#1 em disco; esta página faz isso no navegador.
Autoteste
Corre o motor da página contra âncoras independentes: geração de chaves em três tamanhos de módulo, ciclos de cifrar/decifrar OAEP, assinar/verificar PSS e PKCS#1 v1.5 com várias funções de hash, uma assinatura v1.5 determinística byte a byte (gerada por uma implementação nativa independente), um texto cifrado OAEP fixo e uma assinatura PSS produzida pelo OpenSSL que esta página tem de decifrar/verificar (interoperabilidade entre implementações), ciclos de conversão de formato PEM, e testes negativos (assinatura adulterada, chave errada têm de falhar). Nada é enviado para lado nenhum.
Cifragem e assinaturas RSA explicadas do zero
Em resumo: o RSA é criptografia de chave pública — qualquer pessoa pode cifrar para si com a chave pública ou verificar as suas assinaturas, mas só a chave privada pode decifrar ou assinar — e a sua segurança assenta no facto de fatorizar um número de 2048 bits em dois primos estar além de qualquer computador que exista.
O que o RSA calcula de facto

Dois primos e uma porta secreta. Uma chave RSA começa com dois primos aleatórios grandes p e q; o seu produto n (o módulo, daí a "chave de 2048 bits") é publicado na chave pública juntamente com um expoente e (quase sempre 65537). A chave privada é o par d, o inverso modular de e − calculado a partir de p e q — mais atalhos derivados dos primos que aceleram as operações com a chave privada 4×.

Cifrar e assinar são a mesma exponenciação. Cifrar um bloco de mensagem m significa calcular me mod n; decifrar é cd mod n. Assinar um bloco pré-formatado com o expoente privado e verificar com o público é a mesma operação no sentido inverso. Tudo o resto nesta página — OAEP, PSS, PKCS#1 — trata de formatar esse bloco com segurança para que a exponenciação bruta nunca fique exposta.

Porque é que é lento. Uma operação RSA com uma chave de 2048 bits custa da ordem de um milhão de vezes mais CPU do que cifrar um bloco com AES. É por isso que o TLS usa RSA (ou ECC) apenas para acordar uma chave AES aleatória, e depois muda. A mesma regra vale para tudo o que construir: RSA para a chave, AES para os dados.

Tamanho da chave. O comprimento do módulo é o botão de segurança: 1024 bits está quebrado por política (a fatoração está ao alcance de estados), 2048 bits ≈ 112 bits de força simétrica, 3072 bits ≈ 128 bits, 15360 bits igualaria uma chave simétrica de 256 bits. Nota pós-quântica: o algoritmo de Shor quebra o RSA por completo num computador quântico de grande porte — mais uma razão para manter os tempos de vida das chaves finitos.

OAEP: o único preenchimento de cifragem que deve usar

O problema do RSA bruto. O RSA de manual (me mod n sobre a mensagem bruta) é determinístico e maleável: mensagens idênticas cifram-se de forma idêntica, um atacante pode multiplicar um texto cifrado pela cifragem de 2 para que o texto limpo dobre, e mensagens curtas caem por encontro-no-meio. Nunca deve ser usado diretamente.

O que o OAEP faz. O OAEP (PKCS#1 v2, RFC 8017) mistura a mensagem com uma semente aleatória através de uma rede de Feistel baseada em hash antes da exponenciação. O resultado: a cifragem é aleatória (o mesmo texto limpo dá um texto cifrado diferente de cada vez — execute o Exemplo OAEP duas vezes e compare), a adulteração é detetada na decifragem, e a mensagem tem de caber dentro do módulo com espaço para o hash — o limite k−2·hashLen−2 tabelado acima.

O rótulo. Uma cadeia pública opcional vinculada ao preenchimento. Ambos os lados têm de fornecer o mesmo rótulo ou a decifragem falha — tal como o AAD no AES-GCM, permite vincular o texto cifrado a um contexto (um nome de ficheiro, um identificador de algoritmo). Vazio é normal.

A cifragem PKCS#1 v1.5 está ausente de propósito. O preenchimento da era de 1993 não tem integridade e deixa fugas de informação através do comportamento dos erros de decifragem (o ataque de Bleichenbacher de 1998 transforma um oráculo de preenchimento em decifragem total com alguns milhões de textos cifrados elaborados; continua a quebrar sistemas reais como o ROBOT, em 2017). O WebCrypto recusa implementá-lo; esta página também.

Assinaturas PSS vs PKCS#1 v1.5

Assinar = calcular o hash, depois preencher, depois exponenciar. Ambos os esquemas calculam o hash da mensagem (SHA-256/384/512 aqui), formatam o resumo num bloco e aplicam o expoente privado. A verificação reformata o bloco com a chave pública e compara. A diferença está na formatação:

EsquemaConteúdo do blocoPropriedades
RSASSA-PKCS1-v1_5resumo + cabeçalho DigestInfo, determinísticoCada assinatura da mesma mensagem é idêntica byte a byte (verifique o autoteste: o seu vetor v1.5 é fixo). Suporte legado universal: certificados X.509, JWT RS*, TLS antes da 1.3. Não se conhece nenhuma falsificação quando a verificação é implementada corretamente.
RSA-PSSresumo + sal aleatório do tamanho do hash, mascaramento MGF1Aleatório — cada assinatura é diferente. Provadamente seguro no modelo do oráculo aleatório; exigido nos certificados TLS 1.3 do futuro e nos protocolos mais recentes. O verificador tem de conhecer o tamanho do sal (esta página usa o tamanho do hash, o padrão comum).

Qual escolher. Desenhos novos: PSS. Interoperabilidade com certificados existentes, JWT (RS256) ou pares antigos: v1.5. Ambos são seguros como esquemas de assinatura — a história do desastre v1.5 diz respeito ao preenchimento de *cifragem*, uma construção diferente apesar do nome semelhante.

PKCS#1 vs PKCS#8 vs SPKI: porque é que a mesma chave tem quatro PEM

PEM é apenas DER em base64. Um ficheiro PEM é uma etiqueta mais o base64 de uma estrutura DER (ASN.1 binária). A etiqueta diz-lhe qual a estrutura — e essa é toda a diferença entre os quatro formatos que esta página gera:

Etiqueta PEMEstrutura DERContém
-----BEGIN PUBLIC KEY-----SubjectPublicKeyInfo (SPKI)OID do algoritmo + chave pública (n, e). A "chave pública" predefinida em toda a parte.
-----BEGIN RSA PUBLIC KEY-----PKCS#1 RSAPublicKeyApenas (n, e). OpenSSL antigo e algumas pilhas embutidas.
-----BEGIN PRIVATE KEY-----PKCS#8 PrivateKeyInfoOID do algoritmo + chave privada. Contentor independente do algoritmo, o padrão moderno.
-----BEGIN RSA PRIVATE KEY-----PKCS#1 RSAPrivateKeyn, e, d, p, q, …. A saída clássica do genrsa do OpenSSL.

A mesma chave, invólucros diferentes. As quatro caixas acima, depois de Gerar, contêm o mesmo par de chaves — SPKI e PKCS#1 público contêm n e e idênticos; PKCS#8 e PKCS#1 privado contêm valores privados idênticos. Esta página converte entre eles sem perdas no navegador (o seu autoteste faz ciclos de conversão). Confundir os formatos é a causa mais comum de erros de "chave inválida" ao colar chaves entre ferramentas.

PEMs cifrados (-----BEGIN ENCRYPTED PRIVATE KEY-----) são PKCS#8 com uma camada de cifragem baseada em palavra-passe. Esta página não os aceita — decifre-os offline primeiro (openssl pkcs8 -in enc.pem -out plain.pem).

Erros comuns
  • Cifrar dados volumosos com RSA. Além do limite rigoroso de tamanho do OAEP é absurdamente lento. O padrão é: gerar uma chave AES aleatória, cifrar a chave AES com RSA-OAEP, cifrar os dados com AES-GCM, e enviar as duas partes.
  • Enviar a chave privada porque "é um teste". As chaves de exemplo incorporadas nos vetores desta página são publicadas de propósito — só podem assinar dados de teste. As suas chaves não são assim.
  • Verificar com a chave privada. Normalmente "funciona" matematicamente e algumas ferramentas permitem-no, mas distribuir uma chave privada aos verificadores destrói todo o modelo. Verifique com a chave pública (esta página impõe isso).
  • Comparar assinaturas byte a byte para verificar código. PSS (e OAEP) são aleatórios: duas execuções corretas produzem saídas diferentes. Compare verificando, não por igualdade — só as assinaturas v1.5 são determinísticas.
  • Chaves de 1024 bits "porque são mais rápidas". Também estão ao alcance de uma fatorização bem financiada. O argumento da velocidade morreu com a cifragem híbrida: o RSA corre uma vez por sessão, não por byte.
  • Fixar um tamanho de sal diferente do tamanho do hash para o PSS. O verificador tem de concordar; o tamanho do hash (a escolha desta página e o -sigopt rsa_pss_saltlen:32 do OpenSSL) é o padrão interoperável.
FAQ

Porque é que a minha decifragem falhou com "chave errada, hash errado ou texto cifrado corrompido"? A decifragem OAEP falha quando: não é a chave privada correspondente, o hash difere do lado de cifragem, o rótulo difere, ou foi alterado um byte do texto cifrado. O erro é deliberadamente idêntico em todos os casos — revelar qual a verificação que falhou já é uma fuga de oráculo de preenchimento.

Consigo obter a chave pública a partir da privada? Sim — os formatos privados também contêm n e e. Esta página mostra ambos depois de Gerar; o OpenSSL faz isso com openssl pkey -in priv.pem -pubout.

Porque é que 65537 como expoente? É primo, tem apenas dois bits a 1 (exponenciação rápida), e é suficientemente grande para evitar os ataques de expoente baixo que afetam e=3. É a escolha padrão desde os anos 90; um expoente "estranho" costuma significar uma chave fraca ou não padrão.

O RSA está morto por causa dos computadores quânticos? Ainda não — não existe nenhuma máquina capaz de executar o algoritmo de Shor sobre um módulo de 2048 bits. Mas os dados que têm de permanecer secretos até aos anos 2030+ já estão a ser migrados; os esquemas híbridos PQC são a resposta de engenharia.

E o openssl rsautl? É o antecessor obsoleto do pkeyutl. Por omissão usa o preenchimento de cifragem v1.5 — mais uma razão para ter sido retirado.