我正在编写一个 bash 脚本来自动解密某个文件;然而,该文件是以 16 字节块加密的,而不是简单地对其整体进行编码。
这是一些伪代码来简要解释我为什么要这样做:
cat encrypted.bin | \
buffer and output 16 bytes when asked | \
openssl --args >> decrypted.bin
我本质上需要打开和关闭管道才能分割数据,并且不确定如何在 bash 中完成此操作。我已经查看过split
,但由于加密文件可能有几个 GB,因此我不想执行那么多磁盘写入操作。
我还应该指出,我想知道是否有一种方法可以在不循环多个管道的情况下执行此操作。
答案1
我相信你可以用dd
dd 允许您从文件中读取并将输出发送到您想要指定块大小的位置。
从手册页
描述 复制文件,根据操作数进行转换和格式化。
bs=BYTES read and write up to BYTES bytes at a time
所以我猜
dd if=encrypted.bin bs=16|openssl --args >> decrypetd.bin
应该为你工作。虽然我没有用openssl测试过。
更新基于 jordamn 的评论(感谢 jordamn)
内联方式不会将所有内容直接传输到 openssl 中,而是将 16 个块传输到管道中。
#Get the file size in bytes
total=`ls -l encrypted.bin|awk '{print $5}'`
echo $total;
ret=0;
i=0;
counter=0;
while [ $counter -lt $total ]
do
#counter to know how many block we read
counter=$(($i * 16))
#skip is the number of block based on our setting to skip
dd if=encrypted.bin skip=$i ibs=16 bs=16 count=1 status=none |openssl --args >> decrypit.bin
i=$(($i+1))
done
答案2
对于最近的 Linux(或任何具有最新 GNU coreutils 的系统),调用split --filter
。
<decrypted.bin split -b 16 --filter='openssl --args "$FILE" >> decrypted.bin'
独立加密的块听起来像 ECB,所以openssl enc -d aes-128-ecb
可能就是您所追求的。
如果您有 openssl 命令行工具不支持的奇怪模式,那么您最好使用支持该奇怪模式的工具。 (如果你描述一下模式,我也许可以提供建议。)
您希望已经知道这一点,但如果您不使用标准模式(ECB 除外),您的加密可能不安全。
答案3
分割和缓冲流的另一种方法可能是xxd - make a hexdump or do the reverse
与 it-c
和-p
选项一起使用。
# test
n=0
printf '%s' {1..1000} |
xxd -p -c 16 |
while IFS="" read -r hexstr; do
n=$((n+1))
printf '%s\n' "$n: $hexstr size: $((${#hexstr}/2)) bytes"
printf '%s' "$hexstr" | xxd -p -r | wc -c
done
# split up standard output stream in 16 byte blocks to be decrypted
xxd -p -c 16 encrypted.bin |
while IFS="" read -r hexstr; do
printf '%s' "$hexstr" | xxd -p -r | openssl --args >> decrypted.bin
done