Шифровать файлы с помощью PGP в PHP?
Я хочу использовать шифрование PGP для шифрования CSV файлов, я генерирую через PHP script, а затем отправляю этот файл клиенту по электронной почте. Клиент предоставит мне ключ шифрования, который мне нужно использовать для файлов шифрования.
I Googled о PGP и нашел, что это Pretty Good Privacy, также я нашел OpenPGP http://www.openpgp.org/ и GnuPG http://www.gnupg.org/ Каковы эти два типа PGP? и какой из них я должен использовать?
Также как зашифровать файлы, используя PGP в PHP, с ключом, который предоставит мой клиент?
Я слышал этот термин в первый раз, может кто-нибудь помочь в понимании этого и реализации этого в PHP.
Ответы
Ответ 1
Вопрос 1: О PGP
- PGP (Pretty Good Privacy) является продуктом и товарным знаком Symantec Corporation (они купили его несколько лет назад).
- OpenPGP - это стандарт, используемый PGP.
- GnuPG (Gnu Privacy Guard) - это бесплатная версия PGP с открытым исходным кодом.
Итак, что вы хотите сделать, это зашифровать ключ OpenPGP. Какая реализация OpenPGP ваш клиент использует для расшифровки данных, для вас не важно. В PHP обычно используется GnuPG и есть встроенные интерфейсы.
Вопрос 2: Использование GnuPG в PHP
Используйте интерфейс GnuPG, который является расширением, которое можно установить для PHP.
Сначала импортируйте ключ, где $keydata
- это $keydata
открытый ключ ASCII:
<?php
$gpg = new gnupg();
$info = $gpg -> import($keydata);
print_r($info);
?>
Затем используйте этот ключ для шифрования данных, на этот раз используя отпечаток ключа клиента:
<?php
$gpg = new gnupg();
$gpg -> addencryptkey("8660281B6051D071D94B5B230549F9DC851566DC");
$enc = $gpg -> encrypt("just a test");
echo $enc;
?>
Если вы хотите зашифровать файлы, прочитайте и передайте их в encrypt()
. Обязательно используйте по крайней мере длинные идентификаторы клавиш (например, DEADBEEFDEADBEEF
), лучшие отпечатки пальцев (как в примере) при ссылках на клавиши; и никогда не используйте короткие идентификаторы (DEADBEEF
), так как они уязвимы для атак коллизий.
Это более полный пример того, как пользователь добавил в руководство по PHP.
Ответ 2
Оставим здесь ответ, так как многие примеры в сети для PHP GnuPG очень скучны, и, надеюсь, это спасет кого-то от разочарования.
По сути, он отражает работу инструмента командной строки GnuPG. Вам нужно импортировать ключ, если он еще не находится в списке ключей gpg, тогда вам нужно выбрать ключ получателя для шифрования/дешифрования.
gpg --import recipients-public-key.asc
gpg -r recipient --encrypt test.txt
Если вы сделали то, что я сделал, и передали ключ в качестве получателя, он не работает!
Непонятно, что это поле находится в руководстве GPG или в документации PHP, которая называет это поле "отпечатком". Проверьте кольцо ключей gpg для вашего недавно импортированного ключа с:
gpg --list-keys
Это выведет что-то вроде этого:
pub rsa2048 2019-04-14 [SC] [expires: 2021-04-14]
0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA
uid [ultimate] Dean Or
sub rsa2048 2019-04-14 [E] [expires: 2021-04-14]
Это даст вам UID, а во второй строке - fingerprint, связанный с каждым ключом. Насколько я могу сказать, вы можете использовать UID и fingerprint в качестве получателя.
Таким образом, ваш код PHP для шифрования может выглядеть так:
// Encrypt
$gpg = new gnupg();
$gpg->seterrormode(gnupg::ERROR_EXCEPTION);
// Check key ring for recipient public key, otherwise import it
$keyInfo = $gpg->keyinfo('0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA');
if (empty($keyInfo)) {
$gpg->import('recipients-public-key.asc');
}
$gpg->addencryptkey('0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA');
echo $gpg->encrypt('This is a test!');
Тогда код получателя будет выглядеть так:
// Decrypt
$gpg = new gnupg();
$gpg->seterrormode(gnupg::ERROR_EXCEPTION);
// Check key ring for recipient private key, otherwise import it
$keyInfo = $gpg->keyinfo('0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA');
if (empty($keyInfo)) {
$gpg->import('recipients-private-key.asc');
}
$gpg->adddecryptkey('0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA', '');
echo $gpg->decrypt($encyptedMessage);
Обратите внимание, что отпечатки пальцев одинаковы как для открытого, так и для личного ключа получателя.
Существует также известная проблема с adddecryptkey, не принимающим ключевую фразу! Вам нужно либо удалить фразу-пароль, либо изменить версию GnuPG.