Зашифровать файлы с помощью PGP в PHP?

Я хочу использовать шифрование PGP для шифрования файлов CSV, которые я создаю с помощью сценария PHP, а затем отправляю этот файл клиенту по электронной почте. Клиент предоставит мне ключ шифрования, который мне нужно использовать для файлов шифрования.

Я погуглил о PGP и обнаружил, что это довольно хорошая конфиденциальность, также я нашел OpenPGP http://www.openpgp.org/ и GnuPG http://www.gnupg.org/ Что это за два типа PGP? и какой из них я должен использовать?

Также, как зашифровать файлы с помощью PGP в PHP с ключом, который предоставит мой клиент?

Я впервые услышал этот термин, может ли кто-нибудь помочь в понимании этого и реализации этого в PHP.


person Prashant    schedule 12.04.2013    source источник


Ответы (2)


Вопрос 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 - защищенный открытый ключ 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.

person Jens Erat    schedule 12.04.2013
comment
После этого, как мне отправить это по почте, я должен просто указать переменную $ enc в качестве тела письма, и тогда программное обеспечение электронной почты с поддержкой PGP сможет прочитать его самостоятельно? или что делать, чтобы это отправить по почте? - person Prashant; 12.04.2013
comment
Вы хотите отправлять зашифрованные файлы в виде вложений или зашифровать всю почту? - person Jens Erat; 12.04.2013
comment
Я не уверен, что клиент сказал зашифровать файл с помощью PGP и отправить его по почте. - person Prashant; 13.04.2013
comment
Уточнение: для addencryptkey требуется отпечаток пальца. Вы можете получить отпечаток пользователя с помощью gpg –fingerprint {user_id}. - person Matthew; 17.03.2015
comment
Никогда не используйте идентификаторы пользователей, особенно короткие (8-значные). См. Что такое конфликт идентификатора ключа OpenPGP?. Для целей программирования / написания сценариев всегда храните и обрабатывайте полный отпечаток пальца. Длинные идентификаторы ключей приемлемы для взаимодействия с пользователем, при использовании коротких идентификаторов ключей для взаимодействия всегда предупреждайте пользователя и убедитесь, что не доверяете чему-либо, не проверяя отпечаток пальца или длинный идентификатор. - person Jens Erat; 17.03.2015
comment
Что означает, когда функция $ gpg - ›encrypt () возвращает пустую строку? Согласно документации php, он должен возвращать зашифрованную строку или false, но я получаю пустую строку. Означает ли это, что gnupg не установлен в системе? - person James; 25.10.2016
comment
Похоже, это хороший кандидат на новый вопрос. Обязательно предоставьте минимальный пример (самый короткий код для воспроизведения проблемы). Вы пропускаете предупреждения и сообщения об ошибках? Функция должна возвращать строку (или FALSE), но пустая строка не должна появляться. - person Jens Erat; 25.10.2016
comment
Если я использую этот код, чтобы просто распечатать информацию. Я всегда получаю ЛОЖЬ. Я пытаюсь использовать открытый ключ клиента в качестве данных ключа и мой открытый ключ, каждый раз выводится FALSE. ‹? Php $ gpg = новый gnupg (); $ info = $ gpg - ›import ($ keydata); print_r ($ информация); ? › - person Asit; 27.10.2016
comment
Пожалуйста, задайте новый вопрос, комментарий Stack Overflow не предназначен для широких обсуждений. - person Jens Erat; 27.10.2016
comment
Так работает ли шифрование PGP только на уровне содержимого файла или на уровне файла? или они в принципе одно и то же? - person Greyson; 23.10.2018
comment
OpenPGP обрабатывает и то, и другое одинаково, с той лишь разницей, что при шифровании файла имя файла поле устанавливается в буквальном пакете данных. - person Jens Erat; 24.11.2018

Я собираюсь оставить здесь ответ, так как многие примеры в сети для 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, а во второй строке - отпечаток пальца, связанный с каждым ключом. Насколько я могу судить, вы можете использовать UID и отпечаток пальца в качестве получателя.

Итак, ваш 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.

person Dean Or    schedule 19.04.2019
comment
Я также пробовал использовать шифрование CSV-файла, но не нашел решения. Мои требования - зашифровать файл CSV и поместить его в SFTP. В php мы можем делать только шифрование на уровне сообщений. - person Naveen BT; 25.05.2021