我有一个想要实时加密的流,但问题是openssl
只有当它可以从标准输入读取足够的字节时才加密,否则它会等待。
看看这些例子:
$ (echo Hello world; sleep 3) | cat -
Hello world
$ (echo Hello world; sleep 3) | openssl base64 | openssl base64 -d
Hello world
在第一种情况下,您会立即看到输出,在第二种情况下,您必须等待三秒钟。
我怎样才能避免这种行为?我尝试过unbuffer -p
和stdbuf -i0
,但它们在这种情况下不起作用。
为了更清楚,我向您展示我如何尝试使用它(这些命令是为了通过网络发送音频流):
### Not encrypted: works well
# Server
nc -ul 1234 | gst-launch fdsrc ! opusparse ! opusdec ! fdsink | pacat --latency-msec=20
# Client
parec --latency-msec=20 | gst-launch fdsrc ! audioparse rate=48000 channels=2 ! opusenc ! fdsink | nc -u localhost 1234
### Encrypted: doesn't work
# Server
nc -l -u 1234 | openssl aes-256-cbc -pass pass:test -salt -d | gst-launch fdsrc ! opusparse ! opusdec ! fdsink | pacat --latency-msec=20
# Client
parec --latency-msec=20 | gst-launch fdsrc ! audioparse rate=48000 channels=2 ! opusenc ! fdsink | openssl aes-256-cbc -pass pass:test -salt | nc -u localhost 1234
答案1
在你的例子中你做错了两件事。
- 您正在使用分组密码。您需要使用流密码,例如 rc4,或 CFB 模式下的分组密码(这可以有效地将其转换为流密码)。
- 您正在使用 base64 进行编码。正如 Gilles 提到的,openssl 中的 base64 需要 80 字节缓冲区。消除 base64 编码,您将看到您期望的行为。
示例aes-128-cfb
:
(echo Hello world ; sleep 3) | openssl enc -aes-128-cfb -pass pass:test -bufsize 1 | openssl enc -d -aes-128-cfb -pass pass:test -bufsize 1
示例rc4
:
(echo Hello world ; sleep 3) | openssl enc -rc4 -pass pass:test -bufsize 1 | openssl enc -d -rc4 -pass pass:test -bufsize 1
但是,我必须指出,减小缓冲区大小会增加执行加密操作所需的 CPU 时间:
% time sh -c 'dd if=/dev/urandom bs=8k count=1 | openssl enc -rc4 -pass pass:test | openssl enc -d -rc4 -pass pass:test > /dev/null'
1+0 records in
1+0 records out
8192 bytes transferred in 0.001175 secs (6972350 bytes/sec)
sh -c 0.01s user 0.01s system 167% cpu 0.009 total
% time sh -c 'dd if=/dev/urandom bs=8k count=1 | openssl enc -rc4 -pass pass:test -bufsize 1 | openssl enc -d -rc4 -pass pass:test -bufsize 1 > /dev/null'
1+0 records in
1+0 records out
8192 bytes transferred in 0.001070 secs (7655913 bytes/sec)
sh -c 0.02s user 0.03s system 187% cpu 0.027 total
使用 8K 缓冲区时,用户和系统时间各只花费 0.01 秒,但 using-bufsize 1
分别花费 0.02 和 0.03 秒,总共增加了 5 倍。 CPU 百分比报告值也增加了 20。如果这对您来说不是问题,那么请务必使用 1 的 bufsize。但如果是,那么您需要对其进行基准测试,以找到适合您的应用程序的最佳大小。
答案2
unbuffer
类似的解决方案不起作用,因为延迟不是由 stdio 缓冲引起的,而是由 openssl 程序处理其数据的方式引起的。
openssl base64
,openssl enc
默认openssl dec
缓冲区大小为 8kB,可以使用选项指定-bufsize
。当输入或输出为 Base64 时,缓冲区大小不会减少超过 80 个字节,因为 openssl 希望能够一次处理完整的 Base64 行。
… | openssl aes-256-cbc -pass pass:test -salt -bufsize 16 | …