- A chave e a IV são derivadas da senha que você especifica, usando um algoritmo específico do OpenSSL do qual a equipe do OpenSSL não se orgulha. Eles o mantêm por causa da compatibilidade com versões anteriores, mas eles recomendam que você use melhores funções de derivação de chave baseadas em senha, como o PBKDF2 do PKCS.
O algoritmo de derivação de chave sob medida do OpenSSL está na função EVP_BytesToKey (3) .
Chave:
-K key the actual key to use: this must be represented as a string comprised only of hex digits.
IV:
In cryptography, an initialization vector (IV) or starting variable (SV)[1] is a fixed-size input to a cryptographic primitive that is typically required to be random or pseudorandom.
Portanto, o IV é uma entrada adicional usada para criptografar o arquivo. Não é não a chave (eu acho que é apenas terminologia).
2 Um sal é um prefixo (adicional) para a chave que você especificar. (veja Wikipedia . Torna impossível usar tabelas de arco-íris ou tabelas de hash pré-calculadas em sua chave. geralmente é armazenado sem criptografia.
3 A saída será binária e provavelmente conterá caracteres não imprimíveis. Seu emulador de terminal tentará renderizar esses valores de byte como caracteres imprimíveis em sua codificação e fonte padrão, mas eles provavelmente serão parecidos com "texto lixo" e não estarão seguros para copiar / colar, FTP ou e-mail.
4 Para descriptografar um texto criptografado, você precisa da chave e IV. Se você não tiver um ou ambos, e os que estiver faltando forem derivados da Senha, então, se você tiver a Senha, poderá deduzir novamente a chave e / ou IV da Senha. Você não precisa do Sal, porque você já o tem; é pré-pendente para o início do texto criptografado. O Salt não é realmente um segredo, é apenas uma maneira de evitar tabelas hash pré-computadas e tabelas rainbow.
5 Conforme definido em EVP_BytesToKey (3) , se você usar uma senha de "1" e --nosalt
, os primeiros 16 Bytes da sua chave serão:
md5( D_0 || password || salt)
(observe que, nesse contexto, ||
significa concatenação, não lógico or
)
que é equivalente a
md5 ( 'null' || "1" || 'null')
que é equivalente a
md5("1")
O que acaba sendo
0xc4ca4238a0b923820dcc509a6f75849b
Esse valor é o que a página man chama de D_1
.
Os bytes restantes necessários da chave e IV são gerados assim:
md5( D_1 || password || salt)
que é equivalente a
md5( 0xC4CA4238A0B923820DCC509A6F75849B || "1" || 'null' )
que é equivalente a
md5( 0xC4CA4238A0B923820DCC509A6F75849B31 )
(observe que o ASCII "1" torna-se 0x31 concatenado no final do valor D_1
)
que acaba por ser:
0x7976c7161415c830816dd4068a1d9a52
que é o que essa página man chama D_2.
A chave só precisa de mais 8 bytes do que D_1
já provada, então leva os primeiros 8 bytes de D_2 e se torna:
Key: C4CA4238A0B923820DCC509A6F75849B7976c7161415c830
O IV precisa apenas de 8 bytes e, como há 8 bytes não usados de D_2, eles se tornam o IV:
IV: 816dd4068a1d9a52
Aqui está uma linha de comando para gerar D_1, os primeiros 16 bytes da chave (dado seu exemplo de senha "1" e --nosalt
):
echo -n "1" | openssl md5
Aqui está uma linha de comando para gerar D_2, os 8 bytes restantes da chave, mais todos os 8 bytes do IV (novamente, dados os exemplos de entrada):
echo -n "$(echo -n "1" | openssl md5 -binary)1" | md5
Isso funciona tirando a saída de D_1 (certificando-se de mantê-la em binário, em vez de traduzi-la em dígitos hexadecimais codificados em ASCII), anexando "1" (0x31) a ela e tomando md5
disso.