Compatibilidade de criptografia entre TCL e openssl

1

Eu tenho um script de shell e um script tcl usando o mecanismo de criptografia e quero ter a mesma saída de cifra de ambos os scripts.

por exemplo, a cifra de saída do script tcl e do script de shell deve ser a mesma. O mecanismo de criptografia que desejo usar é o AES ou o DES. (e estou aberto a usar qualquer mecanismo de criptografia como uma questão de fato)

O problema é que ambos os scripts estão produzindo textos cifrados diferentes.

Em tcl eu estou usando o seguinte comando:

[aes::aes -mode cbc -dir encrypt -key 1234567891012345 hi]

e no script de shell:

echo -n "hi" | openssl enc -aes-128-cbc -nosalt -pass pass:1234567891012345

Eu assumi que o resultado de ambos os comandos será o mesmo, mas não é. Estou processando nenhuma opção de salt para que a mesma cifra seja gerada a partir do script de shell se o comando for executado duas vezes.

Existe alguma maneira de obter o mesmo texto cifrado usando scripts diferentes?

    
por Aditya Mayank Shankar 07.10.2017 / 23:45

1 resposta

2

Se você disser openssl enc para usar uma frase secreta, ela será sempre alimentada por um KDF, nunca usada diretamente como a chave; usar -nosalt não desativa isso. (Você pode usar a opção openssl enc -p para ver qual chave e o IV está sendo de fato usado.) Para especificar uma chave bruta, você precisa da opção -K .

(Observe que openssl enc -K valor deve ser em hexadecimal, enquanto aes::aes -key é interpretado como dados binários brutos.)

O outro problema é o preenchimento. Como o AES é uma cifra de bloco, todos os dados de entrada devem ser preenchidos para um múltiplo de 16 bytes (o tamanho do bloco AES) e há vários métodos de preenchimento com diferentes propriedades de segurança. O módulo Tcl aes usa preenchimento zero simples, estendendo os dados com 0x00 bytes.

Enquanto isso, o OpenSSL usa o preenchimento PKCS # 7 e preenche o bloco com um valor correspondente ao tamanho do bloco. Por exemplo, se sua entrada tem apenas 2 bytes, ela precisa de 14 bytes de preenchimento, então, de acordo com o PKCS # 7, cada byte do bloco também terá o valor 14 (0x0E).

( man enc fala do PKCS # 5, que é um documento mais antigo que define o esquema de preenchimento apenas para blocos de 8 bytes. O PKCS # 7 definiu mais tarde o mesmo esquema for any block size .)

Para o modo CBC, você também precisa especificar um IV (16 bytes, igual ao tamanho do bloco AES). O módulo Tcl usa um todo-zeros IV por padrão. Embora o CBC use apenas o IV para os blocos 2 e posteriores, ele não afeta a saída para texto curto.

Portanto, concluindo, isso fornecerá resultados idênticos (usando preenchimento zero):

aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex "hi"

printf 'hi
aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex \
         "hi\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e"

printf 'hi' \
  | openssl enc -aes-128-cbc \
    -K 31323334353637383931303132333435 \
    -iv 00000000000000000000000000000000 \
  | hexdump -C
set data "hi"
set pad [expr {16 - ([string length $data] % 16)}]
append data [string repeat [format %c $pad] $pad]
aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex $data
aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex "hi"

printf 'hi
aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex \
         "hi\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e\x0e"

printf 'hi' \
  | openssl enc -aes-128-cbc \
    -K 31323334353637383931303132333435 \
    -iv 00000000000000000000000000000000 \
  | hexdump -C
set data "hi"
set pad [expr {16 - ([string length $data] % 16)}]
append data [string repeat [format %c $pad] $pad]
aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex $data
%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%' \ | openssl enc -aes-128-cbc -nopad \ -K 31323334353637383931303132333435 \ -iv 00000000000000000000000000000000 \ | hexdump -C
%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%%pre%' \ | openssl enc -aes-128-cbc -nopad \ -K 31323334353637383931303132333435 \ -iv 00000000000000000000000000000000 \ | hexdump -C

Estes também (usando o preenchimento PKCS # 7):

%pre%

Para implementar o preenchimento:

%pre%     
por 08.10.2017 / 00:35