web-dev-qa-db-fra.com

Crypter des fichiers en utilisant PGP en PHP?

Je veux utiliser le cryptage PGP pour crypter un fichier CSV, je le génère via un script PHP puis j'envoie ce fichier au client par e-mail. Le client me donnera la clé de cryptage, dont j'ai besoin utiliser pour les fichiers de chiffrement.

J'ai cherché sur PGP et j'ai trouvé que c'était une assez bonne confidentialité, j'ai aussi trouvé OpenPGP http://www.openpgp.org/ et GnuPG http://www.gnupg.org/ Quels sont ces deux types de PGP? et lequel dois-je utiliser?

Aussi comment crypter un fichier en utilisant PGP en PHP avec la clé que mon client fournira?

J'ai entendu ce terme la première fois, est-ce que quelqu'un peut aider à comprendre cela et à l'implémenter en PHP.

24
Prashant

Question 1: À propos de PGP

  • [~ # ~] pgp [~ # ~] (Pretty Good Privacy) est un produit et une marque de commerce de Symantec Corporation (ils l'ont acheté il y a quelques années) .
  • OpenPGP est la norme utilisée par PGP.
  • GnuPG (Gnu Privacy Guard) est une implémentation gratuite et open source de PGP.

Donc, ce que vous voulez faire, c'est chiffrer avec une clé OpenPGP. Quelle implémentation d'OpenPGP votre client utilise pour déchiffrer les données n'est pas importante pour vous. Avec PHP, GnuPG est couramment utilisé et il existe des interfaces intégrées.

Question 2: Utiliser GnuPG en PHP

Utilisez interface GnuPG , qui est une extension qui peut être installée pour PHP.

Dans un premier temps, importez la clé, où $keydata Est la clé publique blindée ASCII:

<?php
$gpg = new gnupg();
$info = $gpg -> import($keydata);
print_r($info);
?>

Utilisez ensuite cette clé pour crypter les données, cette fois en utilisant l'empreinte digitale de la clé du client:

<?php
  $gpg = new gnupg();
  $gpg -> addencryptkey("8660281B6051D071D94B5B230549F9DC851566DC");
  $enc = $gpg -> encrypt("just a test");
  echo $enc;
?>

Si vous souhaitez crypter des fichiers, lisez-les et passez-les à encrypt(). Veillez à utiliser au moins des ID de clé longs (par exemple, DEADBEEFDEADBEEF), de meilleures empreintes digitales (comme dans l'exemple) lors du référencement des clés; et n'utilisez jamais d'ID de clé courts (DEADBEEF), car ceux-ci sont vulnérables aux attaques par collision .


C'est un plus exemple complet pour faire les deux ajouté par un utilisateur dans le manuel PHP.

42
Jens Erat

Je vais laisser une réponse ici autant d'exemples sur le net pour PHP GnuPG sont des os très nus et j'espère que cela évite à quelqu'un une certaine frustration.

Fondamentalement, il reflète le fonctionnement de l'outil de ligne de commande GnuPG. Vous devez importer une clé si elle n'est pas déjà dans le trousseau de clés de gpg, puis vous devez sélectionner la clé du destinataire à utiliser pour le cryptage/décryptage.

gpg --import recipients-public-key.asc
gpg -r recipient --encrypt test.txt

Si vous avez fait ce que j'ai fait et passé la clé en tant que destinataire, cela ne fonctionne pas!

Ce n'est pas clair ce que ce champ est dans le manuel GPG ou documentation PHP qui fait référence à ce champ comme "empreinte digitale". Vérifiez le porte-clés de gpg pour votre clé fraîchement importée avec:

gpg --list-keys

Cela produira quelque chose comme ceci:

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]

Cela vous donnera l'UID et sur la deuxième ligne l'empreinte digitale associée à chaque clé. Autant que je sache, vous pouvez utiliser l'UID et l'empreinte digitale comme destinataire.

Ainsi, votre code PHP à chiffrer pourrait ressembler à ceci:

// 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!');

Ensuite, le code du destinataire ressemblera à ceci:

// 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);

Notez que les empreintes digitales sont les mêmes pour la clé publique et privée du destinataire.

Il existe également un problème connu avec adddecryptkey ne prenant pas de phrase secrète! Vous devez soit supprimer la phrase secrète, soit modifier votre version de GnuPG.

1
Dean Or