
Eu tenho um script shell e um script tcl usando 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 shell deve ser a mesma. O mecanismo de criptografia que desejo usar é AES ou DES. (e estou aberto a usar qualquer mecanismo de criptografia, na verdade)
O problema é que ambos os scripts estão produzindo textos cifrados diferentes.
No tcl estou usando o seguinte comando:
[aes::aes -mode cbc -dir encrypt -key 1234567891012345 hi]
e em script de shell:
echo -n "hi" | openssl enc -aes-128-cbc -nosalt -pass pass:1234567891012345
Presumi que o resultado de ambos os comandos seria o mesmo, mas não é. Não estou processando nenhuma opção salt para que a mesma cifra seja gerada a partir do shell script se o comando for executado duas vezes.
Existe alguma maneira de obter o mesmo texto cifrado usando scripts diferentes?
Responder1
Se você pedir openssl enc
para usar uma senha, ela sempre será alimentada por meio de um KDF, nunca usada diretamente como chave; usar -nosalt
não desativa isso. (Você pode usar a openssl enc -p
opção para ver qual chave e IV estão de fato sendo usados.)Para especificar uma chave bruta, você precisa da -K
opção.
(Observe que openssl enc -K
o valor deverá serem hexadecimal,entretanto, aes::aes -key
é interpretado como dados binários brutos.)
A outra questão é o preenchimento. Como AES é uma cifra de bloco,todos os dados de entrada devem ser preenchidospara um múltiplo de 16 bytes (o tamanho do bloco AES) e existem vários métodos de preenchimento com diferentes propriedades de segurança. O módulo Tcl aes
usa preenchimento de zeros 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 tiver apenas 2 bytes, ela precisará de 14 bytes de preenchimento, portanto, de acordo com o PKCS#7, cada byte de preenchimento também terá o valor 14 (0x0E).
( man enc
fala de PKCS#5, que é um documento mais antigo que define o esquema de preenchimento apenas para blocos de 8 bytes. PKCS#7 posteriormente definiu exatamente o mesmo esquemapara qualquer tamanho de bloco.)
Para o modo CBC você também precisaespecifique um IV(16 bytes, igual ao tamanho do bloco AES). O módulo Tcl usa um IV com zeros por padrão. Embora o CBC use apenas o IV para o segundo bloco e posteriores, isso não afeta a saída de texto curto.
Concluindo, eles fornecerão resultados idênticos (usando preenchimento zero):
aes::aes -mode cbc -dir encrypt -key 1234567891012345 -hex "hi"
printf 'hi\0\0\0\0\0\0\0\0\0\0\0\0\0\0' \
| openssl enc -aes-128-cbc -nopad \
-K 31323334353637383931303132333435 \
-iv 00000000000000000000000000000000 \
| hexdump -C
Estes também (usando preenchimento PKCS#7):
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
Para implementar o preenchimento:
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