Шифровать файлы с помощью 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.