Стратегия высокого уровня для этого заключается в следующем:
- Сгенерируйте временный закрытый ключ EC, используя
openssl ec
- Используйте открытый ключ получателя для получения общего секрета с помощью
openssl pkeyutl
- Зашифруйте открытый текст, используя
openssl enc
используя производный секретный ключ
- Сгенерируйте открытый ключ EC из закрытого ключа, используя
openssl ecparam
- Сгенерируйте HMAC из зашифрованного текста в третий файл, используя
openssl dgst
- Удалить закрытый ключ EC и общий секрет
Ручной поток для этого должен примерно выглядеть следующим образом:
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
Сценарий, выполняющий шифрование, должен выглядеть примерно так:
#!/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
Приведенный выше код должен работать, но не может быть оптимальным. Последнее сообщение составлено из temppubkey.pem
, ciphertext.enc
и MAC.bin
, вы можете объединить это любым удобным для вас способом. Обратите внимание, что мой выбор для AES-256-OFB не случаен, а намерен, так как режимы CTR, CCM и GCM недоступны через командную строку. Также обратите внимание, что я предпочел AES-256 стандартному выбору AES-128, потому что мы можем просто подключить туда выход SHA-256. Отметим еще больше, что использование полностью нулевого IV здесь безопасно, поскольку OFB "только" требует уникальных IV для каждого ключа, и каждый ключ является полностью случайным.
Что касается соображений безопасности: этот метод создаст временный закрытый ключ для каждого файла, гарантируя, что все шифрования уникальны, и утечка одного общего секрета не утечет все общие секреты для одной и той же пары партнеров по связи. Вы можете использовать цифровые подписи, чтобы убедиться, что сообщение действительно пришло из того же источника.