OpenSSL 可以解码不含换行符的 base64 数据吗?

sta*_*fry 12 base64 openssl

我在 bash 变量中有两块 base64 数据。base64 数据中通常的换行符已被空格替换,变量基本上是一个非常长的单行字符串。

我可以解码变量中包含的两块 base64 数据,但在尝试执行此操作时遇到了一些细微差别。我想了解我是否正确地处理了这个问题,或者是否有更好的方法来解码不包含换行符的 base64 数据。这是我所拥有的:

第一个块是 350 个字符,我可以像这样成功解码它:

echo ${DATA::350} | openssl base64 -d | wc -c
256
Run Code Online (Sandbox Code Playgroud)

第二个块是 5745 个字符,但上面的命令没有产生预期的结果。IE:

$ echo {DATA:350} | openssl base64 -d | wc -c
432
Run Code Online (Sandbox Code Playgroud)

但是,如果我将换行符放回去,它会起作用:

$ echo ${DATA:350} | tr ' ' "\n" | openssl base64 -d | wc -c
4240
Run Code Online (Sandbox Code Playgroud)

我希望第一个块足够小,可以避免一些行长度问题,并且它似乎是所使用的 base64 解码器的一个功能(两个常见的base64openssl base64,表现不同)。

base64解码器(代替openssl base64)停止在第一无效字符(空格),并因此只是解码而输出的OpenSSL 432个字符(9“线”)的第一个“行”(48个字节的输出数据)。该base64命令有一个选项可以忽略垃圾,所以这是有效的:

$ echo ${DATA:350} | base64 -d -i | wc -c
4240
Run Code Online (Sandbox Code Playgroud)

OpenSSL 解码器似乎没有这样的选项。

此外,删除空格完全适用于base64但不适用于openssl base64

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

$ echo ${DATA:350} | tr -d ' ' | base64 -d | wc -c
4240
Run Code Online (Sandbox Code Playgroud)

因此,最后,我替换了换行符并使用了 OpenSSL 解码器,因为无论如何我都需要进一步处理解码后的数据:

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

但我想了解OpenSSL 可以解码不包含换行符的 base64 数据吗?

Ste*_*ris 18

如果您不需要空格,则将openssl使用以下-A选项处理此问题:

所以:

$ 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 
$ 
Run Code Online (Sandbox Code Playgroud)

我们可以看到base64数据都在一行,可以解码。

man enc解释-A选项。

如果您需要保留空格,则需要删除它们(通过转换为'\n'或删除并使用-A)。

  • RFC 4648 说严格来说,base64 中禁止使用空格(第 3.3 节)和换行符(第 3.1 节)。3.3 节还说在这种情况下,实现必须拒绝数据。因此,`openssl base64 -A` 更接近于严格的解释,这是您期望从安全加密工具中得到的。我猜 coreutils `base64` 更宽松。 (2认同)
  • OpenSSL 在 1990 年代(在 4648 甚至 3548 之前)实现了 base64,主要用于读取和写入“PEM”(真正类似于 PEM)和 S/MIME 文件,两者都需要换行符。`-A` 基本上是“我们已经得到了 `EVP_{En,De}codeBlock` 因素,不妨让人们使用它们”。 (2认同)