パイプを16バイトのシーケンスに分割するには?

パイプを16バイトのシーケンスに分割するには?

特定のファイルを自動的に復号化する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ことです。-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

答え4

複数のパイプを繰り返さずにパイプを16バイトのシーケンスに分割する1つの方法は、次のようなものを使用することです。ストリームメディアまたはバッファー(すでに述べた方法に加えてsplit -b 16)。

cstreamたとえば、dd。読み書き用のブロックサイズを設定するオプションだけでなく、書き込み-b num前に-B num入力ブロックを最大バイトまでバッファリングするオプションもあります。numこの-n numオプションは、コピーするデータの総量をバイトnum数に制限します。

関連情報