A estratégia de alto nível para isso é a seguinte:
- Gere uma chave privada EC temporária usando
openssl ec
- Use a chave pública do destinatário para derivar um segredo compartilhado usando
openssl pkeyutl
- Criptografar o texto sem formatação usando
openssl enc
usando a chave secreta derivada - Gere a chave pública EC a partir da chave privada usando
openssl ecparam
- Gere o HMAC do texto cifrado em um terceiro arquivo usando
openssl dgst
- Exclua a chave privada da EC e o segredo compartilhado
O fluxo manual para isso deve ser mais ou menos o seguinte:
openssl ec -genkey -param_enc explicit -out temppriv.pem -name brainpool512r1
openssl pkeyutl -derive -inkey temppriv.pem -peerkey RecipientsPublicKey.pem -out SharedSecret.bin
openssl dgst -sha256 -out HashedSharedSecret SharedSecret.bin
openssl enc -aes-256-ofb -iv "00000000000000000000000000000000" -K "<Enter Hex From HashedSharedSecret here>" -in YourPlaintextFile -out ciphertext.enc
openssl ecparam -in tempprivkey.pem -pubout -out temppubkey.pem
openssl dgst -sha256 -hmac "<Enter Hex From HashedSharedSecret here>" -out MAC.bin ciphertext.enc
#strip the everything non-hex using your editor from MAC.bin
rm SharedSecret.bin
rm tempprivkey.pem
O script que faz a criptografia deve ter a seguinte aparência:
#!/bin/sh
EphemeralPrivateKey=$(openssl ecparam -genkey -param_enc explicit -name brainpool512r1) #generate the ephmeral private key
PrivateKeyBuffer=$(mktemp) #allocate a file to bufer the private key for the derive operation
PeerPublicKey="$1"
PlainTextFile="$2"
EphemeralPublicKeyFile="$3"
CipherTextFile="$4"
MACFile="$5"
echo -n "$EphemeralPrivateKey" > $PrivateKeyBuffer #buffer the private key
ProcessedDerivedSharedSecret=$(openssl pkeyutl -derive -inkey $PrivateKeyBuffer -peerkey $PeerPublicKey|openssl dgst -sha256) #derive the symmetric key using SHA-256 from the established secret
rm $PrivateKeyBuffer #remove the temporary file
ProcessedDerivedSharedSecret=${ProcessedDerivedSharedSecret#*= } #strip the (stdin)=
openssl enc -aes-256-ofb -iv "0000000000000000000000000000000" -K "$ProcessedDerivedSharedSecret" -in "$PlainTextFile" -out "$CipherTextFile" #encrypt using 0 IV and SHA-256 as key
MACValue=$(openssl dgst -sha256 -hmac "$ProcessedDerivedSharedSecret" "$CipherTextFile") #MAC it
MACValue=${MACValue#*= } #strip the (stdin)=
echo -n "$MACValue" > $MACFile #write the MAC
echo -n "$EphemeralPrivateKey" | openssl ec -param_enc explicit -pubout -out "$EphemeralPublicKeyFile" #write the ephemeral public key
O código acima deve funcionar, mas pode não ser o ideal. A mensagem final é composta de temppubkey.pem
, ciphertext.enc
e MAC.bin
, você pode combinar isso da maneira que preferir. Observe que a minha escolha para AES-256-OFB não é acidental, mas intencional, pois os modos CTR, CCM e GCM não estão disponíveis por meio da linha de comando. Note ainda que eu preferi o AES-256 sobre a escolha padrão do AES-128 aqui, porque podemos simplesmente conectar a saída do SHA-256 nele. Observe ainda que usar um IV a zero é seguro aqui, já que OFB "apenas" requer IVs únicos por chave e cada chave é totalmente aleatória.
Quanto às considerações de segurança: Esse método gerará uma chave privada temporária para cada arquivo, garantindo que todas as criptografias sejam exclusivas e o vazamento de um segredo compartilhado não vazará todos os segredos compartilhados para o mesmo par de parceiros de comunicação. Você pode usar assinaturas digitais para garantir que a mensagem realmente veio da mesma fonte.