Problema de buffer do OpenSSL

3

Eu tenho um fluxo que gostaria de criptografar em tempo real, mas o problema é que openssl criptografar apenas quando ele pôde ler bytes stdin o suficiente, caso contrário, aguarda.

Veja esses exemplos:

$ (echo Hello world; sleep 3) | cat -
Hello world
$ (echo Hello world; sleep 3) | openssl base64 | openssl base64 -d
Hello world

No primeiro caso você vê a saída imediatamente, no segundo você tem que esperar três segundos.

Como eu poderia evitar esse comportamento? Eu tentei unbuffer -p e stdbuf -i0 , mas eles não funcionam nesse caso.

Para ser mais claro, mostro a você como estou tentando usá-lo (esses são comandos para enviar um fluxo de áudio pela rede):

### 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
    
por Francesco Frassinelli 15.06.2013 / 19:27

2 respostas

3

Você está fazendo duas coisas erradas no seu exemplo.

  1. Você está usando uma cifra de bloco. Você precisará usar uma cifra de fluxo, como rc4, ou uma cifra de bloco no modo CFB (que efetivamente a transforma em uma cifra de fluxo).
  2. Você está codificando com base64. Como Gilles mencionou, base64 no openssl requer um buffer de 80 bytes. Elimine a codificação base64 e você verá o comportamento esperado.

Exemplo com 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

Exemplo com rc4 :

(echo Hello world ; sleep 3) | openssl enc -rc4 -pass pass:test -bufsize 1 | openssl enc -d -rc4 -pass pass:test -bufsize 1

No entanto, devo salientar que a redução do tamanho do buffer aumentará o tempo de CPU necessário para executar as operações de criptografia:

% 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

Com um buffer de 8K, o tempo do usuário e do sistema foi de apenas 0,01 segundo, mas usando -bufsize 1 , 0,02 e 0,03 segundos, respectivamente, um aumento total de 5x. O valor relatado da porcentagem de CPU também aumentou em 20. Se isso não for um problema para você, use um tamanho de buffer de 1. Mas, se for, você precisará compará-lo para encontrar o melhor tamanho para sua aplicação. / p>     

por 16.06.2013 / 09:33
3

unbuffer e soluções semelhantes não funcionam porque a latência não é devida ao armazenamento em buffer stdio, é devido à maneira como o programa openssl processa seus dados.

openssl base64 , openssl enc e openssl dec têm um tamanho de buffer padrão de 8kB, que pode ser especificado com a opção -bufsize . Quando a entrada ou saída é base64, o tamanho do buffer não diminui mais do que 80 bytes, pois o openssl quer poder processar uma linha completa de base64 de cada vez.

… | openssl aes-256-cbc -pass pass:test -salt -bufsize 16 | …
    
por 16.06.2013 / 02:07

Tags