¿Puede OpenSSL decodificar datos base64 que no contienen saltos de línea?

9

Tengo dos fragmentos de datos base64 en una variable bash. Los saltos de línea habituales dentro de los datos de base64 han sido reemplazados por espacios y la variable es básicamente una cadena muy larga de una línea.

Puedo decodificar los dos fragmentos de datos de base64 contenidos en la variable, pero experimenté algunos matices al intentar hacerlo. Me gustaría entender si me estoy acercando a esto correctamente o si hay una mejor manera de decodificar datos base64 que no contengan saltos de línea. Esto es lo que tengo:

El primer fragmento tiene 350 caracteres y puedo decodificarlo con éxito así:

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

El segundo fragmento tiene 5745 caracteres, pero el comando anterior no produce los resultados esperados. es decir:

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

Sin embargo, funciona si vuelvo a poner saltos de línea:

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

Espero que haya algún problema de longitud de línea que el primer fragmento es lo suficientemente pequeño como para evitarlo, y parece ser una característica del decodificador base64 que se está utilizando (los dos habituales base64y se openssl base64comportan de manera diferente).

El base64decodificador (en lugar de openssl base64) se detiene en el primer carácter no válido (el espacio en blanco) y, por lo tanto, solo decodifica la primera "línea" (48 bytes de datos de salida) mientras que OpenSSL genera 432 caracteres (9 "líneas"). El base64comando tiene una opción para ignorar la basura , por lo que esto funciona:

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

El decodificador OpenSSL no parece tener esa opción.

Además, eliminar el espacio en blanco funciona por completo base64pero no para openssl base64:

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

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

Entonces, al final, reemplacé las nuevas líneas y usé el decodificador OpenSSL porque de todos modos necesitaba procesar aún más los datos decodificados:

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

Pero me gustaría entender ¿Puede OpenSSL decodificar datos base64 que no contienen saltos de línea?

starfry
fuente
FWIW bash puede cambiar o eliminar caracteres por sí mismo, sin trusar ${var//old[/new}, pero no al mismo tiempo que la subcadena.
dave_thompson_085

Respuestas:

17

Si no necesita espacios, openssllo manejará con la -Aopción:

Entonces:

$ 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 los datos de base64 están todos en una línea y pueden decodificarse.

man encexplica la -Aopción

Si necesita conservar los espacios, deberá eliminarlos (ya sea convirtiéndolos '\n'o eliminándolos y utilizándolos -A).

Stephen Harris
fuente
¡La -Aopción fue una de las primeras cosas que probé, pero lo hice antes de intentar eliminar los espacios y luego "seguir adelante" cuando no funcionó! La página del manual no menciona nada acerca de que los espacios sean un problema. De todos modos, lo he intentado nuevamente con los espacios eliminados y funciona. Todavía es desagradable, pero al menos es solo un tr -d ' '. Es una pena que no pueda procesarlo e ignorar el espacio en blanco (como base64puede).
starfry
2
RFC 4648 dice que estrictamente hablando espacios (sección 3.3) y avances de línea (sección 3.1) están prohibidos en base64. La sección 3.3 también dice que las implementaciones DEBEN rechazar datos en este caso. Por openssl base64 -Alo tanto, está más cerca de ser una interpretación estricta, que esperaría de una herramienta de cifrado de seguridad. Supongo que el coreutils base64es más indulgente.
Stephen Harris
2
OpenSSL implementó base64 en la década de 1990 (antes de 4648 o incluso 3548) principalmente para leer y escribir archivos 'PEM' (realmente similares a PEM) y S / MIME, los cuales requieren saltos de línea. -Aes básicamente "tenemos los EVP_{En,De}codeBlockfactores, también podríamos dejar que la gente los use".
dave_thompson_085