Utilitário de criptografia de arquivos sem verificação de integridade da chave (chave simétrica)

2

Ao criptografar um arquivo com chave simétrica, os utilitários mais comuns (como gpg, mcrypt, etc) armazenam informações na mensagem criptografada que pode ser usada para verificar a integridade da chave durante a descriptografia. Por exemplo, se a chave errada for inserida durante a descriptografia, o gpg será respondido com:

gpg: decryption failed: bad key

Suponha que eu esteja criptografando um arquivo contendo uma string que é aleatória. Em seguida, a verificação de integridade da chave usada nos utilitários padrão adiciona uma vulnerabilidade.

Existe um utilitário comum que não armazena nenhuma informação ou redundância para verificar a integridade de chaves / mensagens (e assim irá "descriptografar" um arquivo criptografado para qualquer chave fornecida)?

    
por udkLpqc 18.02.2015 / 06:54

4 respostas

1

Como alternativa à minha outra outra resposta , gostaria de oferecer outra coisa. Algo bonito ... dm-crypt.

A dm-crypt simples (sem o LUKS) não armazena nada sobre a chave; pelo contrário, cryptsetup está perfeitamente feliz em abrir um dispositivo simples com qualquer senha e começar a usá-lo. Permita-me ilustrar:

[root:tmp]# fallocate -l 16M cryptfile
[root:tmp]# cryptsetup --key-file - open --type plain cryptfile cfile-open <<<"pa55w0rd"

Neste ponto, você desejaria gravar todos os seus dados aleatórios no /dev/mapper/cfile-open . Parece prudente para mim que você dimensione o arquivo de criptografia original apropriadamente antes do tempo para que você use todo o espaço; no entanto, você pode facilmente tratar isso como outro bocado de segurança através da obscuridade e anotar exatamente quantos dados você escreveu. (Isso só funcionaria se os blocos subjacentes já fossem semi-aleatórios, ou seja, se você não for preencher completamente o arquivo, deverá criá-lo com openssl rand ou dd if=/dev/urandom em vez de fallocate .). .. Você poderia até mesmo usar dd para começar a escrever em algum lugar no meio do dispositivo.

Por enquanto, farei algo mais simples.

[root:tmp]# cryptsetup status cfile-open
/dev/mapper/cfile-open is active.
  type:    PLAIN
  cipher:  aes-cbc-essiv:sha256
  keysize: 256 bits
  device:  /dev/loop0
  loop:    /tmp/cryptfile
  offset:  0 sectors
  size:    32768 sectors
  mode:    read/write
[root:tmp]# b $((32768*512))
B         KiB      MiB    GiB  TiB  PiB  EiB
16777216  16384.0  16.00  .01  0    0    0
[root:tmp]# ll cryptfile
-rw-r--r--. 1 root root 16777216 Feb 21 00:28 cryptfile
[root:tmp]# openssl rand -out /dev/mapper/cfile-open $((32768*512))
[root:tmp]# hexdump -n 16 -C /dev/mapper/cfile-open
00000000  00 1d 2d 11 ac 38 c4 d3  cc 81 4f 32 de 64 01 ca  |..-..8....O2.d..|
00000010
[root:tmp]# cryptsetup close cfile-open

Neste ponto, preenchi meu arquivo criptografado com 16 MiB de dados aleatórios. Veja o que acontece quando eu abro novamente usando a frase secreta errada e, em seguida, só para ficar claro, abro novamente com a correta e você verá que os dados originais ainda estão intactos.

[root:tmp]# cryptsetup --key-file - open --type plain cryptfile cfile-open <<<"pass"
[root:tmp]# hexdump -n 16 -C /dev/mapper/cfile-open
00000000  89 97 91 26 b5 46 87 0c  67 87 d8 4a cf 78 e6 d8  |...&.F..g..J.x..|
00000010
[root:tmp]# cryptsetup close cfile-open
[root:tmp]# cryptsetup --key-file - open --type plain cryptfile cfile-open <<<"pa55w0rd"
[root:tmp]# hexdump -n 16 -C /dev/mapper/cfile-open
00000000  00 1d 2d 11 ac 38 c4 d3  cc 81 4f 32 de 64 01 ca  |..-..8....O2.d..|
00000010
[root:tmp]# 

Aproveite.

    
por 21.02.2015 / 07:50
1

O que você quer não pode ser feito com o GnuPG. Pode, no entanto, ser feito com o OpenSSL. Você precisaria usar uma das cifras (preferencialmente AES) em um modo de fluxo como cfb ou ofb. (Veja: link )

Normalmente, quando eu uso o openssl para criptografar dados, eu uso o cbc da seguinte maneira (com ou sem a codificação base64 ( -a ) ... e claro, há outras maneiras de especificar a senha e os dados de entrada ( veja man openssl ):

[rsaw:~]$ openssl aes-256-cbc -e -a -pass pass:pa55w0rd <<<inputdata
U2FsdGVkX180a9K5gBgip7/lgdCGCLLlRflAjK8+YwY=
[rsaw:~]$ openssl aes-256-cbc -e -a -pass pass:pa55w0rd <<<inputdata
U2FsdGVkX1+4uSv4uCNj2J4g7441XDioDoAb6JNn2RU=
[rsaw:~]$ openssl aes-256-cbc -e -a -pass pass:pa55w0rd <<<inputdata |
> openssl aes-256-cbc -d -a -pass pass:pa55w0rd
inputdata

O fato de você obter resultados diferentes a cada vez informa sua senha é salgada, o que geralmente é bom. Agora observe o que acontece quando eu uso uma chave ruim.

[rsaw:~]$ openssl aes-256-cbc -e -a -pass pass:pa55w0rd <<<inputdata |
> openssl aes-256-cbc -d -a -pass pass:pa55w0r
bad decrypt
139867807664032:error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:evp_enc.c:596:

Para encurtar a história, esse modo (cbc) é amplamente usado para criptografar arquivos, mas obviamente não atende aos requisitos estabelecidos. Vamos tentar algo diferente.

[rsaw:~]$ openssl aes-256-cfb1 -e -a -pass pass:pa55w0rd <<<inputdata
U2FsdGVkX1+p64nx+/K6yCHdHw+Nmn6fSOg=
[rsaw:~]$ openssl aes-256-cfb1 -e -a -pass pass:pa55w0rd <<<inputdata |
> openssl aes-256-cfb1 -d -a -pass pass:pa55w0rd
inputdata
[rsaw:~]$ openssl aes-256-cfb1 -e -a -pass pass:pa55w0rd <<<inputdata |
> openssl aes-256-cfb1 -d -a -pass pass:pa55w0r
'G�疏s�v

Enquanto o acima atende às suas necessidades, não dou garantias. Eu não sou especialista em criptografia. A criptografia é um grande negócio. É complicado. Eu vou dizer que aes*cfb* e aes*ofb também atendem aos seus requisitos ... e que você deve pular aes*ecb .

Eu vou oferecer mais 2 petiscos interessantes:

  1. Eu normalmente nunca recomendaria o uso de chaves sem sal, mas no caso do que você está fazendo (criptografando dados aleatórios) ... você poderia pular o sal, pois adiciona uma estrutura mais claramente definida ao início dos dados. Por exemplo:

    [rsaw:~]$ openssl aes-256-cfb1 -e -a -pass pass:pa55w0rd <<<inputdata
    U2FsdGVkX18aMT3eK4IH+XWGhp4dOSG9UJQ=
    [rsaw:~]$ openssl aes-256-cfb1 -e -a -pass pass:pa55w0rd <<<inputdata
    U2FsdGVkX18uIlFFMbsZib11UgjuITY9rNw=
    [rsaw:~]$ openssl aes-256-cfb1 -e -a -pass pass:pa55w0rd <<<inputdata
    U2FsdGVkX1+G9lAIj7RjafT9YNfO9RQXDjU=
    [rsaw:~]$ openssl aes-256-cfb1 -e -nosalt -a -pass pass:pa55w0rd <<<inputdata
    X2zi09uo6ale8A==
    
  2. Quando eu armazeno dados (incluindo dados criptografados), a integridade é sempre uma das minhas principais preocupações. Se houver alguma perda de dados, eu quero saber para que eu possa jogar fora todo o arquivo. Usando uma cifra de bloco como aes*cbc com openssl (ou AFAIK usando o GnuPG para esse propósito), qualquer pequeno bit-flip será capturado e causará falha na descriptografia. Por outro lado, se você fizer certo, usar um modo de fluxo pode permitir que você recupere o máximo de dados possível - ele mantém a corrupção local na parte do fluxo onde ele existe. Verifique:

    [rsaw:tmp]$ openssl aes-256-cfb1 -e -a -pass pass:pa55w0rd </etc/services >services.asc
    [rsaw:tmp]$ wc -l services.asc 
    13965 services.asc
    [rsaw:tmp]$ sed '6000q;d' services.asc
    e6AAnnXAF74c8p52q7+klGC+JHfK91QOx+oFonAzKFoJt0DSNg2WQkdBaxv4YLst
    [rsaw:tmp]$ sed -i '6000s/^e/f/' services.asc 
    [rsaw:tmp]$ sed '6000q;d' services.asc
    f6AAnnXAF74c8p52q7+klGC+JHfK91QOx+oFonAzKFoJt0DSNg2WQkdBaxv4YLst
    [rsaw:tmp]$ openssl aes-256-cfb1 -d -a -pass pass:pa55w0rd <services.asc | diff - /etc/services
    5029c5029,5030
    < veronica        2770/tcp           %���#��*����@jeronica        2770/udp                # Veronica
    ---
    > veronica        2770/tcp                # Veronica
    > veronica        2770/udp                # Veronica
    

Aproveite.

PS: Não ouse usar algo diferente de gpg , openssl ou dm-crypt. Atenha-se aos 3 grandes. Nada mais.

    
por 21.02.2015 / 07:49
-1

Esta ferramenta não armazena nada para verificar a chave.

link

    
por 18.02.2015 / 10:42
-1

@udkLpqc: Não posso comentar acima, cabe a você usar a ferramenta ou não, mas o que você escreveu não é o que eu vejo. Eu compilei o meu próprio no Ubuntu:

$echo -e "uvwxyz\n\n\n\n\n\n\n\n\n\n" | wc -l
11
$echo -e "uvwxyz\n\n\n\n\n\n\n\n\n\n" | ./aes -p "t" | ./aes -d -p "t" | wc -l
11

Isso parece o mesmo número de linhas para mim (eu tive o mesmo resultado usando arquivos). A ferramenta é antiga, a fonte afirma que faz PKCS5, não PKCS7. Ele documenta porque ecoa a senha e o uso de strlen em vez de strnlen, bem, isso deve ser visto no contexto, a ferramenta espera que a entrada venha diretamente de um usuário e use strlen apenas para nomes de arquivos e senha. Se você planeja usá-lo em algum contexto automatizado, onde o nome do arquivo e a senha vêm de fontes não confiáveis, eu concordo, pode não funcionar para você.

    
por 19.02.2015 / 10:22