Preenchimento - algoritmo de criptografia
-
05-07-2019 - |
Pergunta
Estou escrevendo uma implementação do algoritmo de criptografia XXTEA que funciona em "fluxos", ou seja, pode ser usado como: Crypt MyKey <MyFile> Saída.
Um dos requisitos é que ele não tem acesso ao arquivo (ele apenas lê um bloco de tamanho fixo até encontrar um EOF). O algoritmo precisa de que os bytes de dados sejam múltiplos de 4; portanto, é necessário adicionar um preenchimento.
Para texto simples, uma boa solução é preencher com nulos e, na descriptografia, ignoram os nulos, mas a mesma estratégia não pode ser usada para fluxos binários (que podem conter nulos incorporados).
Eu li as soluções comuns, como preencher com o número de chars ausentes (se errar 3 chars, anexar um 3, 3, 3 no final) e etc, mas me pergunto: há uma solução mais elegante?
Solução
Lendo a pergunta, parece que o aspecto de segurança disso é discutível. Simplificando, você tem uma API que espera um múltiplo de 4 bytes como entrada, o que você nem sempre tem.
Aprender até 3 bytes em qualquer fluxo binário é perigoso se você não conseguir garantir que o fluxo binário não se importe. Aprender 0 no final de um arquivo exe não importa, pois os arquivos exe têm cabeçalhos especificando os tamanhos relevantes de todos os bits restantes. Aprender 0 no final de um arquivo PCX o quebraria, pois os arquivos PCX possuem um cabeçalho que inicia um número específico de bytes a partir do final do arquivo.
Então, na verdade, você não tem escolha - não há escolha de bytes de preenchimento mágico que você possa usar que sejam garantidos para nunca ocorrer naturalmente no final de um fluxo binário: você devo Sempre anexe pelo menos um dword adicional de informações que descrevem os bytes de preenchimento usados.
Outras dicas
Ler: http://msdn.microsoft.com/en-us/library/system.security.cryptography.paddingmode.aspx
Tem uma lista de métodos comuns de preenchimento, como:
PKCS7 - A sequência de preenchimento do PKCS #7 consiste em uma sequência de bytes, cada um dos quais é igual ao número total de bytes de preenchimento adicionados.
A sequência de preenchimento Ansix923 consiste em uma sequência de bytes preenchidos com zeros antes do comprimento.
A sequência de preenchimento ISO10126 consiste em dados aleatórios antes do comprimento.
Exemplos:
Dados brutos: 01 01 01 01 01
PKCS #7: 01 01 01 01 01 03 03 03
Ansix923 01 01 01 01 01 00 00 03
ISO10126: 01 01 01 01 01 CD A9 03
Leia sobre roubo de texto cifrado. É indiscutivelmente muito mais elegante que o preenchimento de texto simples. Além disso, sugiro que o uso de um tamanho de bloco maior que 4 bytes - 64 bits é provavelmente o mínimo.
Estritamente falando, a criptografia faça você mesmo é uma idéia perigosa; É difícil vencer os algoritmos que toda a comunidade criptográfica tentou e não conseguiu quebrar. Divirta -se e considere ler isto, ou pelo menos algo da seção "Leitura relacionada" de Schneier.
Na verdade, eu esperaria que uma boa cifra não precise de preenchimento. O RC4, por exemplo, não precisa de preenchimento e é uma cifra de fluxo muito forte. No entanto, pode ser atacado se o invasor puder alimentar diferentes dados escolhidos com a rotina de criptografia, que sempre usa a mesma chave e também tiver acesso aos dados criptografados. Escolher os dados de entrada corretos e analisar os dados de saída pode ser usada para restaurar a chave de criptografia, sem um ataque de força bruta; Mas, além disso, o RC4 é muito seguro.
Se precisar de preenchimento, não é um fluxo cifra IMHO. Como se você estivesse um múltiplo de 4 bytes ou um múltiplo de 16 bytes, qual é a enorme diferença? E se for acolchoado para ser um múltiplo de 16 bytes, você poderá usar praticamente qualquer cifra de bloco. Na verdade, sua cifra é uma cifra de bloco, apenas funciona com 4 blocos de bytes. Era uma cifra de fluxo em um sistema em que todo "símbolo" é de 4 byte (por exemplo, quando a criptografia UTF-32 Text; nesse caso, os dados sempre serão um múltiplo de 4, com certeza, portanto, nunca há preenchimento).