Você digita uma senha em um gerenciador de arquivos compactados e, um instante depois, um arquivo se abre. Entre esses dois momentos há uma curta cadeia de passos que decide o quanto a proteção é forte e como um programa distingue uma senha certa de uma errada. Essa cadeia é a proteção por senha do ZIP em funcionamento, e segui-la da senha digitada até o arquivo desbloqueado mostra exatamente de onde vem a sua força.
Uma senha ZIP nunca criptografa nada diretamente. A ferramenta a transforma em material de chave, seja semeando as três chaves internas do ZipCrypto, seja executando PBKDF2 para o WinZip AES. Essa chave criptografa os bytes comprimidos de cada arquivo. Pequenos valores armazenados, um byte de checagem ou um valor de verificação, permitem descartar senhas erradas a baixo custo antes que uma etapa de confirmação aceite a certa.
Da senha à chave
Os dois esquemas partem da mesma entrada, os bytes da sua senha (UTF-8 nas ferramentas modernas). É no que acontece com esses bytes em seguida que os dois esquemas se separam.
ZipCrypto: três chaves, sem alongamento
O ZipCrypto, o esquema tradicional da PKWARE, guarda todo o seu estado em três chaves de 32 bits. Elas começam em constantes fixas, e cada byte da senha as atualiza por sua vez: a primeira chave passa por uma atualização de tabela CRC-32 com o byte da senha, a segunda absorve o byte baixo da primeira e é multiplicada por uma constante, e a terceira passa por uma atualização CRC-32 com o byte alto da segunda. Essa é toda a derivação de chave.
Não há sal nem alongamento. Dois arquivos protegidos com a mesma senha partem de um estado de chaves idêntico, e testar uma candidata custa apenas um punhado de operações aritméticas. As fraquezas de texto claro conhecido que decorrem desse projeto são tratadas na explicação do ZipCrypto.
WinZip AES: PBKDF2 com um sal por entrada
O WinZip AES trata a senha como a entrada de uma função deliberadamente lenta. A ferramenta lê primeiro um byte de força no campo extra da entrada: 1 significa AES-128, 2 significa AES-192 e 3 significa AES-256. Esse byte fixa o comprimento da chave em 16, 24 ou 32 bytes e o do sal em 8, 12 ou 16 bytes.
Em seguida, ela executa PBKDF2-HMAC-SHA1 por 1000 iterações sobre a senha e um sal aleatório armazenado com aquela entrada. A saída é dividida em três partes: a chave de criptografia AES, uma chave de autenticação separada de mesmo comprimento e um valor de verificação de senha de 2 bytes. Como cada entrada carrega o próprio sal, a mesma senha gera chaves diferentes em entradas diferentes, e tabelas pré-calculadas não ajudam. As 1000 iterações se repetem para cada bloco de 20 bytes de material de chave, então uma única tentativa custa, de propósito, entre dois mil cálculos HMAC-SHA1 (AES-128) e quatro mil (AES-256), três mil no AES-192. A página sobre o WinZip AES cobre a criptografia em modo CTR em si e as variantes AE-1 e AE-2.
Como uma ferramenta sabe que a senha está certa
Descriptografar e descompactar um arquivo inteiro para cada candidata seria desperdício, então os dois formatos armazenam um valor pequeno que um leitor pode checar primeiro. Essa checagem é um filtro, não uma prova. Quem passa por ela segue para um teste de confirmação completo. Uma única entrada basta; o ZipRecover prefere a menor entrada criptografada grande o bastante para confirmar uma senha de forma decisiva (entre as entradas de até 256 MB comprimidos), o que mantém cada confirmação barata. Se todas as entradas testáveis forem arquivos ZipCrypto com menos de 4 bytes, o resultado informa que a senha passou apenas por uma verificação rápida. Se a única entrada testável usar um método de compressão diferente de Store ou Deflate, a ferramenta só pode comparar o comprimento descriptografado, no qual a senha certa normalmente também falha, então a busca normalmente termina sem resultado. Se todas as entradas criptografadas passarem de 256 MB comprimidos, a ferramenta mostra um erro em vez de buscar.
| Esquema | Primeira checagem rápida | Confirmação |
|---|---|---|
| ZipCrypto | Descriptografar o cabeçalho de criptografia de 12 bytes e comparar seu último byte com um byte de checagem conhecido (o byte alto do CRC-32 armazenado, ou o da hora de modificação quando um descritor de dados é usado): um filtro de cerca de 1 em 256 | Descriptografar o resto da entrada, descompactá-la e comparar o CRC-32 e o tamanho do resultado com os valores do diretório central |
| WinZip AES | Comparar o valor de verificação de 2 bytes produzido pelo PBKDF2 com o armazenado logo após o sal: um filtro de cerca de 1 em 65.536 | Recalcular o HMAC-SHA1 sobre o texto cifrado com a chave de autenticação e comparar os primeiros 10 bytes com o código de autenticação armazenado |
Os dois filtros não são iguais. Cerca de 1 senha errada em 256 passa pelo byte de checagem do ZipCrypto, e o passo de descriptografia e CRC precisa capturá-la; esse passo é uma soma de verificação, não uma prova criptográfica, embora uma senha errada que ainda se descompacte limpamente com o tamanho e o CRC-32 corretos seja extremamente improvável em arquivos reais. No AES, cerca de 1 senha errada em 65.536 sobrevive ao valor de verificação, e o passo HMAC-SHA1 que vem depois é criptograficamente definitivo: uma senha AES confirmada nunca é um falso positivo.
Observe onde o custo recai. No ZipCrypto, as duas etapas são baratas. No AES, a parte cara, o PBKDF2, roda antes do filtro, então o filtro só economiza o HMAC, e o esquema pode se dar ao luxo de tornar cada tentativa lenta.
O que isso significa para uma senha esquecida
Nenhum passo dessa cadeia pode ser pulado. Não dá para perguntar a senha a um arquivo; uma ferramenta só pode propor candidatas e passar cada uma pelos passos acima. A recuperação depende, portanto, do tamanho do espaço a ser pesquisado e da velocidade com que cada candidata pode ser testada.
Um cálculo ilustrativo mostra a escala. Tome uma senha de 12 caracteres com letras maiúsculas, minúsculas e dígitos: 62^12, cerca de 3,2 × 10^21 candidatas. Na taxa de um único núcleo para AES-256 que o site mediu com o seu script de prova, cerca de 640 tentativas por segundo, esgotar esse espaço leva 3,2 × 10^21 ÷ 640, cerca de 5 × 10^18 segundos, ou aproximadamente 1,6 × 10^11 anos (160 bilhões de anos). Mesmo na taxa do ZipCrypto medida da mesma forma, cerca de 240.000 tentativas por segundo, o mesmo espaço exige algo da ordem de 4 × 10^8 anos. Os dois números são modelados a partir dessas taxas medidas, não medidos em nenhum arquivo específico, e adicionar núcleos só os divide de forma linear.
Agora encolha o espaço com o que você lembra. Se você sabe que a senha tinha seis letras minúsculas, isso dá 26^6, cerca de 309 milhões de candidatas, que os mesmos 640 por segundo cobrem em aproximadamente 5,6 dias em um núcleo, ou cerca de 17 horas distribuídas em oito threads de trabalho (de novo, ilustrativo). Um prefixo conhecido, um comprimento lembrado ou uma lista de palavras pessoal reduzem a busca muito mais do que um hardware mais rápido. O guia sobre quanto tempo leva a recuperação de uma senha ZIP detalha essas taxas.
Tudo acima diz respeito ao conteúdo de cada entrada. Os nomes, tamanhos e datas no diretório central continuam legíveis em um ZIP criptografado padrão; o guia sobre o que um arquivo ZIP criptografado protege cobre essa visão do contêiner e como reconhecer o esquema em uso.
Se o arquivo é seu e a senha se perdeu, anote primeiro o que você lembra sobre a forma dela e depois execute uma recuperação privada da sua senha ZIP no navegador. A ferramenta lê o byte de força, prefere a menor entrada criptografada grande o bastante para confirmar uma senha de forma decisiva (entre as entradas de até 256 MB comprimidos) e aplica exatamente a cadeia de filtro e confirmação descrita aqui, somente no seu dispositivo.
Fontes
- PKWARE, APPNOTE.TXT, especificação do formato de arquivo .ZIP: estrutura do contêiner, o bit de criptografia e a criptografia tradicional da PKWARE (o escalonamento de chaves do ZipCrypto e o cabeçalho de 12 bytes).
- WinZip, AES Encryption Information: especificação de criptografia AE-1 e AE-2: o campo extra 0x9901, o byte de força, os tamanhos de sal e chave, PBKDF2 com 1000 iterações, o valor de verificação de 2 bytes e o código de autenticação HMAC-SHA1 de 10 bytes.
- IETF, RFC 8018, PKCS #5: especificação de criptografia baseada em senha, versão 2.1: a definição do PBKDF2.