(Encontrei um tópico no Twitter com uma explicação muito legal das cifras simétricas. Foi escrito por Colm MacCárthaigh, um dos principais colaboradores do Apache. Pedi permissão a Colm para traduzir, ele concordou gentilmente).
Vou explicar em linguagem simples o que acontece quando os dados são criptografados. Espero que sem o misticismo e as coisas complexas que foram inventadas pelos criptógrafos.
Portanto, a criptografia simétrica é exatamente o que usamos na maioria dos casos quando queremos criptografar um monte de dados. Seu navegador envia e recebe dados usando criptografia simétrica. Se você criptografar arquivos ou um disco, a criptografia simétrica também funcionará nesse caso. iMessage, Signal, WhatsApp - todos eles usam criptografia simétrica para a segurança da sua correspondência.
Se você acha que, ao criptografar os dados, eles são misturados para que ninguém possa lê-los sem uma chave, da maneira que realmente acontece.
Aqui está um exemplo simples. Suponha que eu tenha uma string Ovaltine e queira criptografá-la. Eu poderia usar rot13 - a cifra muito simples da velha escola de César, que faz uma dança redonda das letras em que a e z dão as mãos e substitui cada letra por outra letra do alfabeto, com 13 caracteres da letra substituída. Assim, "O" se transforma em "B" e "v" se torna "i", como resultado, "Ovaltine" se transforma em "Binygvar". Claro, isso não é muito seguro. Este é um exemplo ingênuo, fácil de quebrar, pois o invasor pode descobrir qual letra é mais frequentemente encontrada (geralmente no texto original é "e") e encontrar as letras restantes dessa maneira.
Agora você pode imaginar que deve haver maneiras mais complicadas de "misturar" as letras. Por exemplo, algum esquema complexo no qual "a" vai para "p", mas quando re-criptografado, para "f". Talvez até algumas vezes esse esquema comece a criptografar "a" com duas letras, por exemplo, "jd" ou outra coisa. Portanto, esse esquema complicado pode criptografar "Ovaltine" na string "FGyswDmweeRq" (observe que ele se tornou mais longo). No passado, surgiram algoritmos de criptografia que funcionavam de maneira semelhante, mas não é assim que funciona a criptografia moderna.
Em vez de "embaralhar" as letras, a criptografia moderna pega sua cadeia secreta e as combina artisticamente com dados aleatórios. Isso é semelhante ao rot13 apenas em dois aspectos: criptografia e descriptografia são essencialmente a mesma operação e tudo acontece "no lugar". Na verdade, você notou que o rot13 é um algoritmo de criptografia e descriptografia? rot13 (Ovaltina) -> Binygvar, rot13 (Binygvar) -> Ovaltina. Eu acredito que essa é uma simetria muito bonita na criptografia simétrica. Mas voltando ao nosso tópico. O truque é que usamos a operação XOR bit a bit. Em criptografia, lógica formal e código, os programas XOR podem ser definidos de maneira diferente, mas usarei uma notação que você provavelmente conhece. Parece assim: ^.
XOR significa "OR exclusivo". Este é um operador (ou função, se você preferir), que recebe dois argumentos e retorna o resultado. A ^ B = C. Este operador é chamado "bit a bit" porque se aplica aos bits correspondentes um ao outro. Se A e B são bytes, podemos assumir que A ^ B = C são essencialmente 8 operações diferentes que ocorrem simultaneamente. ^ compara o primeiro bit A e o primeiro bit B e, em seguida, coloca o resultado no primeiro bit C. Ele repete as mesmas 7 vezes mais para os bits restantes. As regras são simples: se o bit de A for "1" OU o bit de B for "1", definiremos o bit C correspondente como "1", mas apenas se "A" e "B" não forem "1" ao mesmo tempo. Esta é a parte exclusiva. Aqui está uma tabela de verdade da velha escola:
A|B|C 0|0|0 1|0|1 0|1|1 1|1|0
O mais legal do XOR é que ele se parece com rot13. Podemos usá-lo para criptografia e descriptografia. Vou mostrar isso com um exemplo simples. Vamos imaginar que queremos criptografar o número usual "3" e que nossa chave de criptografia é outro número "7". Assim, 3 ^ 7 = 4. Ou seja, o resultado da criptografia é "4". Vamos agora decifrar o número. Farei a mesma coisa novamente: 4 ^ 7 = 3. Pegue qualquer número que desejar ou qualquer dado, e ele sempre funcionará - o XOR sempre poderá se descriptografar.
Pouco a pouco - é assim que realmente criptografamos e descriptografamos dados, não há mixagem, apenas XOR-ing. A parte difícil é encontrar dados aos quais podemos aplicar o XOR. Uma abordagem é pegar um grande pedaço de dados secretos em mãos e usá-los como o segundo argumento para o XOR. Nesse caso, todos os participantes no processo de transmissão de dados criptografados devem usar o mesmo conjunto de dados secretos para criptografia e descriptografia. E vai funcionar. É verdade que existem vários problemas.
O primeiro problema Dados secretos devem parecer aleatórios. Você não pode receber texto de um livro ou algo assim. Quaisquer padrões aparecerão nos dados criptografados. Foi exatamente isso que tornou as forças aliadas superiores na Segunda Guerra Mundial.
O segundo problema. Você não pode reutilizar dados confidenciais, pois os padrões reaparecem. Portanto, você precisa fornecer grandes quantidades de dados secretos para todos que precisam, como o One-time pad. Isso é muito difícil.
Na criptografia moderna, "geramos" os dados secretos necessários a partir de pequenas chaves. Essas chaves são muito mais fáceis de transportar e proteger. Isto é o que realmente são os algoritmos de criptografia simétrica - esquemas para a geração determinística de dados aleatórios a partir de uma chave. A parte sobre “determinismo” é muito importante: duas pessoas com a mesma chave devem gerar absolutamente o mesmo conjunto de dados, caso contrário, elas não serão capazes de se entender. Você provavelmente já ouviu falar sobre esses algoritmos: AES, 3DES, DES, RC4, ChaCha20. Todos fazem isso.
Acontece que o problema matemático de gerar um fluxo de dados aleatório (no qual não há padrões de qualquer forma previsível) usando a chave é muito difícil. Nesta lista, apenas o AES e o ChaCha20 são considerados seguros hoje. Outros algoritmos foram invadidos: as pessoas foram capazes de prever. Além disso, a AES tem uma reputação um pouco manchada, porque os criptografadores dizem o seguinte:
O AES é o principal e mais analisado algoritmo de criptografia. Absolutamente Gold Standard! : dark_sunglasses:
Mas, ao mesmo tempo, eles adicionam:
As implementações de AES no software (não no hardware) são inseguras ou lentas, e às vezes não são seguras e lentas. Ele não foi projetado levando em consideração o fato de poder ser hackeado usando a análise de cache. : facepalm:
Não tenha muito medo se isso não estiver claro para você. A idéia principal é a seguinte: o AES é maravilhoso do ponto de vista da matemática, mas é muito complicado na implementação de software. Mas não se preocupe - quase sempre temos suporte AES no nível do hardware (uma lista de todos os processadores com suporte ao hardware AES pode ser encontrada aqui https://en.wikipedia.org/wiki/AES_instruction_set , - nota do tradutor).
Seja como for, continuamos ... Como esses algoritmos realmente funcionam? Como podemos pegar uma chave e gerar com segurança um fluxo de dados aleatório? Vou simplificar um pouco as coisas aqui e começar com blocos.
Esses algoritmos recebem três parâmetros na entrada e fornecem o texto cifrado na saída. Parâmetros de entrada - uma chave, texto criptografado e ... surpresa - algo estranho chamado "vetor de inicialização" (vetor de inicialização, IV).
AES(key, IV, plaintext) -> encrypted_data.
A chave e o IV são combinados entre si para criar um conjunto de "condições iniciais" para o algoritmo; isso é semelhante à troca ou embaralhamento inicial de peças em um jogo de Scrabble. A mesma combinação de chave e IV sempre criará o mesmo conjunto de condições iniciais. Você pergunta, por que precisamos de IV então? Precisamos de um IV para que possamos criptografar várias mensagens usando a mesma chave. Sem IV, cada fluxo de dados gerado seria o mesmo, e isso é ruim. Isso violaria uma das regras de que falamos anteriormente: não podemos reutilizar os mesmos dados para criptografia. Então, precisamos de um IV para misturar o resultado. Mas, diferentemente da chave IV, ela pode ser pública.
Portanto, quando você criptografa uma mensagem e a envia para alguém, também pode adicionar: "Ei, aqui está o IV que eu usei". Ainda é fundamental que não reutilizemos a combinação de chave e IV, pois eles nos forneceriam dados aleatórios repetidos. Existem duas maneiras de atingir essa condição: 1) IV é um tipo de contador que aumentamos a cada nova mensagem. 2) IV é gerado aleatoriamente, embora tenha um valor bastante grande, portanto, não precisamos nos preocupar muito com colisões. Seja como for, mencionei que vou falar sobre blocos.
As teclas e IV são "misturadas" ou combinadas de forma a criar um conjunto de condições iniciais ... essas condições são realmente o "bloco" inicial de dados aleatórios. O comprimento deste bloco é de 128 bits para AES128, 256 bits para AES256 e 512 bits para ChaCha20. E aqui se manifesta a verdadeira magia e individualidade de um algoritmo de criptografia específico. De fato, sua essência está em como a sequência de blocos é gerada e como cada bloco está associado aos seus vizinhos. O relacionamento entre esses bloqueios permanece previsível, mesmo para quem não possui uma chave.
Não vou me aprofundar em como esses algoritmos funcionam, mas se você quiser saber mais, recomendo que comece a explorar esse tópico com os geradores congruenciais lineares (LCG). LCG é uma função que cria blocos de dados "circulares" de maneira aleatória e não repetitiva. Então dê uma olhada nas redes Feistel, o próximo nível de desenvolvimento de LCG. Depois lide com as S-Boxes e veja como o Salsa20 cria entrelaçamento no algoritmo ChaCha20. Tudo isso é muito mais acessível do que você imagina!
Portanto, agora sabemos como um fluxo de dados aleatório pode ser combinado com o texto para criptografar e descriptografá-lo, e já estamos um pouco no assunto de como esses fluxos de dados aleatórios são criados. Não é tudo o que precisamos? Para criptografia de disco, isso é quase tudo. Podemos criptografar cada bloco ou setor do armazenamento usando uma chave e IV, que podem ser obtidos a partir da "posição" no disco. Assim, sempre podemos descriptografar qualquer bloco de dados em qualquer lugar do disco, desde que tenhamos a chave. Mas há um problema ... alguém pode arruinar nossos dados criptografados. Se eu alterar o valor de qualquer byte, mesmo que não possua uma chave, no final não poderemos descriptografar o bloco. E não há proteção contra esse tipo de interferência. No caso de enviar mensagens e dados pela rede, isso se torna ainda mais crítico. Não queremos que ninguém estrague nossos dados transmitidos. Portanto, precisamos adicionar uma verificação de integridade! Existem vários esquemas para fazer isso.
HMAC, GCM e Poly1305 são os esquemas de verificação de integridade modernos mais comuns. Esses algoritmos funcionam basicamente assim: eles são fornecidos com dados e outra chave (a chamada chave de integridade). Após os cálculos, eles fornecem o MAC (código de autenticação de mensagem) ou tag, que por sua vez é apenas mais um dado que atua como uma assinatura.
Assim, para criptografia e proteção, nosso esquema pode ser assim:
AES(key, IV, "Ovaltine") -> encrypted_output HMAC(key, encrypted_output) -> MAC
e depois por fio enviamos:
IV | encrypted_output | MAC
Para descriptografia, verificamos o MAC, gerando-o novamente e comparando o resultado com o MAC recebido e, em seguida, descriptografamos os dados. Existem diferenças internas na forma como HMAC, GCM e Poly1305 geram essas assinaturas, mas você não precisa se preocupar com isso. Até o momento, essa combinação de operações geralmente é agrupada em uma função chamada "AEAD" (Criptografia autenticada com dados adicionais). Sob o capô, ela faz tudo o que eu falei anteriormente:
AEAD(key, IV, plaintext, additional_data) -> IV_encrypted_data_MAC
Uma parte chamada "dados_ adicionais" são apenas dados com os quais você pode garantir que a parte remetente possua esses dados, embora não tenham sido enviados a eles. É como metadados que definem direitos de acesso. Geralmente, este campo é deixado em branco.
No entanto, você pode ter problemas com o AEAD se você usar o mesmo IV. Isso é ruim! Existem tentativas de melhorar essa situação: meu colega, cujo nome é Shay, está trabalhando em um esquema legal de SIV que adiciona uma camada de proteção contra esse problema. Mas se você usar um IV exclusivo, a criptografia moderna é muito segura. Ou seja, você pode publicar o texto cifrado no New York Times e ninguém pode decifrá-lo. A cifra permanecerá inacessível mesmo se "parte" do texto for conhecida. Por exemplo, nos protocolos da Internet, uma grande quantidade de texto é conhecida. Os servidores HTTP sempre respondem da mesma forma e os primeiros bytes são sempre conhecidos. Mas esse fato não importa - não ajudará o invasor a descobrir uma única parte dos dados restantes ... Percorremos um longo caminho desde a Segunda Guerra Mundial.
Mas há ataques que funcionam! Se você enviar dados por uma rede e alguém rastrear a hora e o tamanho das mensagens, os dados criptografados poderão ser quebrados usando a análise de tráfego.

Vamos descobrir primeiro o comprimento. Obviamente, o comprimento não é uma característica oculta. E isso é normal se você estiver tentando proteger sua senha ou número do cartão de crédito em algum lugar no meio da mensagem. Não é um grande problema. Mas isso significa que potencialmente qualquer pessoa pode determinar o tipo de conteúdo que você envia. Um exemplo simples: se você enviar um gif usando um messenger e se o tamanho dessa imagem for único, o invasor que interceptar seus dados poderá sugerir qual GIF acabou de ser enviado. Existem versões mais complicadas deste ataque para o Google Maps, Netflix, Wikipedia, etc. Para se proteger contra esse ataque, você pode "finalizar" as mensagens enviadas com bytes adicionais, para que todas as mensagens enviadas tenham o mesmo tamanho, não importa o quê. A criptografia usada nas redes militares sempre “finaliza” o tráfego com dados adicionais, ou seja, para o interceptador sempre parece o mesmo! Outro problema associado ao tamanho é que, se você usar a compactação e permitir ao invasor alterar qualquer parte do conteúdo da página que o usuário vê, isso permitirá que o invasor descubra até os menores segredos. Procure um ataque chamado CRIME. Ela é linda e assustadora.
Eu também disse que o outro problema é o tempo. Obviamente, o horário de envio de cada mensagem é uma informação aberta. Isso pode ser um problema? Talvez! Por exemplo, se você envia uma mensagem sempre que pressiona uma tecla, é trivial descobrir exatamente o que é impresso usando a análise de tempo. Legal! Outro exemplo é o VOIP. Se o seu aplicativo de chamada enviar dados somente quando as pessoas falarem, mas não durante o silêncio, isso será suficiente para restaurar 70% da fala em inglês. Apenas fora do silêncio. Legal assustador.
Estes exemplos são apenas a ponta do iceberg. Mesmo quando você usa algoritmos e esquemas de criptografia que vêm melhorando há 80 anos, ainda existem lacunas que podem ser usadas para quebrar a segurança. É por isso que é valioso saber sobre isso!
Seja como for, este é o nível de explicação em que quero me concentrar agora, mas consideramos as coisas mais necessárias a saber. Se você ler até este ponto - obrigado! Agora você deve entender melhor o que acontece durante a criptografia e o que observar.
Sinta-se livre para fazer perguntas.
A tradução é publicada sob licença CC BY-NC-SA 4.0