O OpenSSL pode decodificar dados base64 que não contêm quebras de linha?

9

Eu tenho dois pedaços de dados base64 em uma variável bash. As quebras de linha usuais nos dados base64 foram substituídas por espaços e a variável é basicamente uma sequência de uma linha muito longa.

Posso decodificar os dois blocos de dados base64 contidos na variável, mas experimentei algumas nuances ao tentar fazer isso. Gostaria de entender se estou abordando isso corretamente ou se há uma maneira melhor de decodificar dados base64 que não contêm quebras de linha. Aqui está o que eu tenho:

O primeiro pedaço tem 350 caracteres e posso decodificá-lo com sucesso da seguinte forma:

echo ${DATA::350} | openssl base64 -d | wc -c
256

O segundo pedaço tem 5745 caracteres, mas o comando acima não produz os resultados esperados. ou seja:

$ echo {DATA:350} | openssl base64 -d | wc -c
432

No entanto, funciona se eu colocar a linha de volta:

$ echo ${DATA:350} | tr ' ' "\n" | openssl base64 -d | wc -c
4240

Espero que exista algum problema no comprimento da linha que o primeiro pedaço seja pequeno o suficiente para evitar, e isso pareceria um recurso do decodificador base64 sendo usado (os dois usuais base64e openssl base64se comportam de maneira diferente).

O base64decodificador (em vez de openssl base64) para no primeiro caractere inválido (espaço em branco) e, portanto, apenas decodifica a primeira "linha" (48 bytes de dados de saída), enquanto o OpenSSL gera 432 caracteres (9 "linhas"). O base64comando tem uma opção para ignorar o lixo , portanto, isso funciona:

$ echo ${DATA:350} | base64 -d -i | wc -c
4240

O decodificador OpenSSL não parece ter essa opção.

Além disso, a remoção do espaço em branco funciona inteiramente para, base64mas não para openssl base64:

$ echo ${DATA:350} | tr -d ' ' | openssl base64 -d | wc -c
400

$ echo ${DATA:350} | tr -d ' ' | base64 -d | wc -c
4240

Então, no final, substituí as novas linhas e usei o decodificador OpenSSL porque precisava processar os dados decodificados de qualquer maneira:

$ openssl enc -d -a -in <(echo ${DATA:350} | /usr/bin/tr ' ' "\n") -aes-256-cbc -pass file:<(echo $skey) | ...

Mas eu gostaria de entender O OpenSSL pode decodificar dados base64 que não contêm quebras de linha?

starfry
fonte
O FWIW bash pode alterar ou excluir os próprios caracteres, sem tr, usando ${var//old[/new}- mas não ao mesmo tempo como substring.
Dave_thompson_085

Respostas:

17

Se você não precisar de espaços, openssllidará com isso com a -Aopção:

Assim:

$ ls -l sp2.bmp
-rw-r--r-- 1 sweh sweh 3000054 Apr 21 20:13 sp2.bmp
$ x=$(openssl base64 -A < sp2.bmp)                
$ echo "$x" | wc
      1       1 4000073
$ echo "$x" | openssl base64 -d -A > res
$ ls -l res
-rw-r--r-- 1 sweh sweh 3000054 Jul 30 10:00 res
$ cmp res sp2.bmp 
$ 

Podemos ver que os dados base64 estão todos em uma linha e podem ser decodificados.

man encexplica a -Aopção

Se você precisar manter os espaços, será necessário removê-los (convertendo para '\n'ou excluindo e usando -A).

Stephen Harris
fonte
A -Aopção foi uma das primeiras coisas que tentei, mas o fiz antes de tentar remover os espaços e depois "seguir em frente" quando não funcionou! A página de manual não menciona nada sobre os espaços serem um problema. Enfim, eu apenas tentei novamente com os espaços removidos e funciona. Ainda é desagradável, mas pelo menos é apenas um tr -d ' '. É uma pena que não possa processá-lo e ignore o espaço em branco (como base64pode).
starfry
2
A RFC 4648 diz que, estritamente falando, os espaços (seção 3.3) e os feeds de linha (seção 3.1) são proibidos na base64. Seção 3.3 também diz implementações devem rejeitar dados neste caso. Portanto, openssl base64 -Aestá mais perto de ser uma interpretação estrita, o que você esperaria de uma ferramenta de criptografia de segurança. Eu acho que o coreutils base64é mais brando.
Stephen Harris
2
O OpenSSL implementou o base64 nos anos 90 (antes de 4648 ou mesmo 3548) principalmente para ler e gravar arquivos 'PEM' (realmente parecidos com PEM) e arquivos S / MIME, os quais requerem quebras de linha. -Aé basicamente "nós temos os EVP_{En,De}codeBlockfatores, podemos deixar que as pessoas os usem".
Dave_thompson_085