Bisakah OpenSSL mendekode data base64 yang tidak mengandung jeda baris?

9

Saya punya dua potongan data base64 dalam variabel bash. Pemutusan garis biasa dalam data base64 telah digantikan oleh spasi dan variabel pada dasarnya adalah satu string satu baris yang sangat panjang.

Saya dapat men-decode dua potongan data base64 yang terkandung dalam variabel tetapi saya mengalami beberapa nuansa ketika mencoba melakukannya. Saya ingin memahami apakah saya mendekati ini dengan benar atau apakah ada cara yang lebih baik untuk mendekode data base64 yang tidak mengandung jeda baris. Inilah yang saya miliki:

Potongan pertama adalah 350 karakter dan saya dapat mendekodekannya dengan sukses seperti ini:

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

Potongan kedua adalah 5745 karakter tetapi perintah di atas tidak menghasilkan hasil yang diharapkan. yaitu:

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

Namun, itu berfungsi jika saya mengembalikan garis:

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

Saya berharap ada beberapa masalah panjang garis bahwa potongan pertama cukup kecil untuk dihindari, dan itu akan muncul sebagai fitur dari decoder base64 yang digunakan (dua yang biasa, base64dan openssl base64, berperilaku berbeda).

The base64decoder (bukan openssl base64) berhenti di karakter yang tidak valid pertama (spasi) dan oleh karena itu hanya menerjemahkan pertama "line" (48 byte data output) sedangkan OpenSSL output 432 karakter (9 "garis"). The base64perintah memiliki opsi untuk mengabaikan sampah , jadi ini bekerja:

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

Dekoder OpenSSL tampaknya tidak memiliki opsi seperti itu.

Juga, menghapus whitespace sepenuhnya berfungsi untuk base64tetapi tidak openssl base64:

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

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

Jadi, pada akhirnya, saya mengganti baris baru dan menggunakan decoder OpenSSL karena saya masih perlu memproses data yang sudah diterjemahkan:

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

Tapi saya ingin mengerti Bisakah OpenSSL mendekode data base64 yang tidak mengandung jeda baris?

starfry
sumber
FWIW bash dapat mengubah atau menghapus karakter itu sendiri, tanpa tr, menggunakan ${var//old[/new}- tetapi tidak pada saat yang sama dengan substring.
dave_thompson_085

Jawaban:

17

Jika Anda tidak membutuhkan spasi maka opensslakan menangani ini dengan -Aopsi:

Begitu:

$ 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 
$ 

Kita dapat melihat data base64 semuanya dalam satu baris, dan dapat diterjemahkan.

man encmenjelaskan -Aopsi.

Jika Anda perlu menjaga spasi maka Anda harus menghapusnya (baik dengan mengonversi '\n'atau menghapus dan menggunakan -A).

Stephen Harris
sumber
The -Apilihan adalah salah satu hal pertama yang saya mencoba, tapi saya melakukannya sebelum mencoba untuk menghapus spasi dan kemudian "pindah" ketika itu tidak bekerja! Halaman manual tidak menyebutkan apa pun tentang spasi yang menjadi masalah. Ngomong-ngomong, saya baru saja mencobanya lagi dengan spasi yang dihapus dan tidak berfungsi. Ini masih jahat tetapi setidaknya itu hanya tr -d ' '. Sayang tidak bisa memprosesnya dan mengabaikan ruang putih (seperti base64kaleng).
Starfry
2
RFC 4648 mengatakan bahwa ruang yang benar-benar berbicara (bagian 3.3) dan umpan garis (bagian 3.1) dilarang di base64. Bagian 3.3 juga mengatakan implementasi HARUS menolak data dalam kasus ini. Jadi openssl base64 -Alebih dekat untuk menjadi interpretasi yang ketat, yang Anda harapkan dari alat enkripsi keamanan. Saya kira coreutil base64lebih lunak.
Stephen Harris
2
OpenSSL mengimplementasikan base64 pada 1990-an (sebelum 4648 atau bahkan 3548) terutama untuk membaca dan menulis file 'PEM' (benar-benar seperti PEM) dan S / MIME, keduanya membutuhkan linebreak. -Apada dasarnya adalah "kita punya EVP_{En,De}codeBlockfaktor, mungkin juga membiarkan orang menggunakannya".
dave_thompson_085