Executando verificação de segurança...
1

Passou um bom tempo antes de eu precisar recorrer à essa conversa aqui novamente. Pesquisando a respeito do assunto, realmente faz sentido suas dicas, cyp. Daí pensei, o que posso fazer com o que tenho disponível:

  • a "aplicação XOR" escrita em C;
  • o openssl disponível no sistema.

Preferi o openssl nesse experimento para testar suas possibilidades. Assim, usando um arquivo TXT como exemplo:

msg_hex="57652063616EE2809974207475726E206261636B2074686520636C6F636B206275742077652063616E20676574206168656164206F662069742E2E2E2073746F7265206E6F772C2064656372797074206C61746572"

ou

cat message.dat | hexdump -Cv
00000000  57 65 20 63 61 6e e2 80  99 74 20 74 75 72 6e 20  |We can...t turn |
00000010  62 61 63 6b 20 74 68 65  20 63 6c 6f 63 6b 20 62  |back the clock b|
00000020  75 74 20 77 65 20 63 61  6e 20 67 65 74 20 61 68  |ut we can get ah|
00000030  65 61 64 20 6f 66 20 69  74 2e 2e 2e 20 73 74 6f  |ead of it... sto|
00000040  72 65 20 6e 6f 77 2c 20  64 65 63 72 79 70 74 20  |re now, decrypt |
00000050  6c 61 74 65 72                                    |later|
00000055

e encriptando a mensagem com aes-256-ctr (ao invés de aes-256-cbc), passando os 16 bytes do vetor de inicialização (IV) e os 32 bytes da chave derivada,

iv_hex="4DFF8852F1A0521514EB57A47D6C60E0"
key_hex="31AE978DB130B660C8922073BD7BACAC1F4D0CA4159FA2803DD3320CA5FB212D"

obtém-se os bytes encriptados (em vez de bloco encriptado)

cat message.dat | openssl enc -aes-256-ctr -iv ${iv_hex} -K ${key_hex} | hexdump -Cv
00000000  83 75 5d ac 28 82 01 5e  6e e1 c8 b1 b4 2b b9 74  |.u].(..^n....+.t|
00000010  da a2 a2 d5 72 2d 31 87  f6 ec 4d be 7f 95 49 40  |....r-1...M...I@|
00000020  5f 8c a1 80 47 6a 09 f3  ce e9 96 db 68 63 48 1b  |_...Gj......hcH.|
00000030  dc 9c 47 10 02 62 3e f8  5d da 5e 8c 2b d1 77 28  |..G..b>.].^.+.w(|
00000040  48 15 e2 e8 f1 0b f8 63  13 da 0b 8c d3 f3 14 18  |H......c........|
00000050  f4 83 2f a1 c0                                    |../..|

Para decriptar a stream de bytes,

cat message.dat | openssl enc -aes-256-ctr    -iv ${iv_hex} -K ${key_hex} | \
                  openssl enc -aes-256-ctr -d -iv ${iv_hex} -K ${key_hex} | hexdump -Cv

obtém-se a mensagem original, como esperado

00000000  57 65 20 63 61 6e e2 80  99 74 20 74 75 72 6e 20  |We can...t turn |
00000010  62 61 63 6b 20 74 68 65  20 63 6c 6f 63 6b 20 62  |back the clock b|
00000020  75 74 20 77 65 20 63 61  6e 20 67 65 74 20 61 68  |ut we can get ah|
00000030  65 61 64 20 6f 66 20 69  74 2e 2e 2e 20 73 74 6f  |ead of it... sto|
00000040  72 65 20 6e 6f 77 2c 20  64 65 63 72 79 70 74 20  |re now, decrypt |
00000050  6c 61 74 65 72                                    |later|
00000055

Neste exemplo, o modo counter (-aes-256-ctr) parece ser mais seguro que o modo block (-aes-256-cbc), pois durante a decriptação neste último modo, considerando que a chave derivada está corretamente informada mas o IV incorreto e contendo todos os bytes nulos, boa parte da mensagem original vai surgir, pois somente o primeiro bloco estará comprometido:

1Password uses AES128, in CBC mode to encrypt data – and it’s the design of CBC that enables the next optimization. If you have the wrong IV when you decrypt in CBC mode it corrupts the first block – but only the first block, the rest will be fine.
https://adamcaudill.com/2013/04/16/1password-pbkdf2-and-implementation-flaws

Ao informar a chave derivada como parâmetro para o openssl, o conteúdo resultante não irá conter os bytes mágicos e o salt logo nos primeiros 16 bytes, pois são desnecessários quando a chave derivada é fornecida em vez do password em texto plano e, opcionalmente, o salt. Logo, tanto a chave como o IV devem ser armazenados em outro lugar seguro e os bytes resultantes, aparentemente sem qualquer dica sobre o que são (sem header).

iv_hex="4DFF8852F1A0521514EB57A47D6C60E0"
key_hex="31AE978DB130B660C8922073BD7BACAC1F4D0CA4159FA2803DD3320CA5FB212D"

No modo aes-256-ctr, o conteúdo resultante da encriptação conterá os bytes aleatórios com comprimento igual ao da mensagem (stream) original (abaixo em hex), ou seja, algo sem sentido algum se os elementos de segurança forem perdidos.

msg_enc_hex="74733B62D4EEE423EBBAA78F68520F3EDA426F7A2C7B515F0797BDE35EEA59D115A2B3927382774A45A51EFDCF4BE819276907F5EBA9EC0C8A1D9DF389800ABF0D5B5A648D9F305DC25757BD69251F75BE337B35ED"

Para decriptação, exige-se o conhecimento desses dois elementos de segurança, ou seja, o IV e a chave. Em caso da chave e/ou IV fornecidos estarem incorretos, bytes aleatórios serão obtidos na saída, sem qualquer advertência como ocorre no caso do modo block (-aes-256-cbc).

000000000000000:error:00000000:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt:../crypto/evp/evp_enc.c:999:

A meu ver, essa advertência é um tipo de ajuda no caso de um ataque de força bruta para a chave. [In]felizmente o mesmo não acontece caso um IV incorreto seja fornecido na decriptação.

Carregando publicação patrocinada...