Como posso dividir um pipe em seqüências de 16 bytes?

3

Estou escrevendo um script para automatizar a descriptografia de um determinado arquivo; no entanto, o arquivo é criptografado em blocos de 16 bytes, em vez de simplesmente codificado em sua totalidade.

Aqui está um código do psuedo para explicar brevemente o que estou tentando fazer:

cat encrypted.bin | \
buffer and output 16 bytes when asked | \
openssl --args >> decrypted.bin

Eu essencialmente preciso que o pipe abra e feche para dividir os dados, e não tenho certeza de como isso pode ser feito no bash. Eu olhei para split , mas como o arquivo criptografado pode ter vários GBs, não quero executar muitas gravações em disco.

Também devo salientar que gostaria de saber se existe uma maneira de fazer isso sem fazer um loop por vários canais.

    
por tjbp 08.07.2013 / 13:58

5 respostas

1

Com Linux recente (ou qualquer sistema com os principais utilitários GNU recentes), chame split --filter .

<decrypted.bin split -b 16 --filter='openssl --args "$FILE" >> decrypted.bin'

Bloqueios criptografados de maneira independente soam como ECB, então openssl enc -d aes-128-ecb pode ser o que você procura.

Se você tem um modo estranho que a ferramenta de linha de comando openssl não suporta, é melhor usar uma ferramenta que suporte esse modo estranho. (Se você descrever o modo, talvez eu possa oferecer sugestões.)

Espero que você já saiba disso, mas se você não estiver usando um modo padrão (exceto o ECB), sua criptografia é provavelmente insegura.

    
por 10.07.2013 / 04:46
7

Eu acredito que você pode usar em vez disso dd

dd permite que você leia a partir de um arquivo e envie a saída para onde você deseja especificar também um tamanho de bloco.

da página de manual

DESCRIPTION Copy a file, converting and formatting according to the operands.

   bs=BYTES
          read and write up to BYTES bytes at a time

Então eu acho que

dd if=encrypted.bin bs=16|openssl --args >> decrypetd.bin

deve funcionar para você. Embora eu não tenha testado com o openssl.

Atualizar com base no comentário do jordamn (obrigado jordamn)

A maneira em linha não canaliza tudo diretamente para o openssl, ao invés disso canaliza 16 blocos.

#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
    
por 08.07.2013 / 14:20
0

Outra maneira de dividir e armazenar em buffer o fluxo pode ser usar xxd - make a hexdump or do the reverse com suas opções -c e -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
    
por 08.07.2013 / 17:55
0

Uma maneira de dividir um pipe em seqüências de 16 bytes sem fazer o loop através de vários canais pode ser usar ferramentas como cstream ou mbuffer (além da abordagem split -b 16 já mencionada).

cstream , por exemplo, é semelhante a dd . Ele não tem apenas uma opção -b num para definir o tamanho de bloco usado para leitura / gravação, mas também uma opção -B num para armazenar em buffer um bloco de entrada até num bytes antes de gravar. A opção -n num limita a quantidade total de dados a serem copiados para num bytes.

    
por 10.07.2013 / 11:59
0
awk '$0=RT' RS=.{16} encrypted.bin |
while read jb
do
  openssl enc -d -base64 <<< $jb >> decrypted.bin
done
    
por 12.05.2014 / 02:52

Tags