Encrypt files using PGP in PHP?

后端 未结 2 600
鱼传尺愫
鱼传尺愫 2020-11-27 15:46

I want to use PGP encryption to encrypt a CSV files, I am generating through a PHP script and then send that file to client via email. Client will give me the encryption key

相关标签:
2条回答
  • 2020-11-27 16:11

    Going to leave an answer here as many examples across the net for PHP GnuPG are very bare bones and hopefully this saves someone some frustration.

    Basically, it mirrors how the GnuPG command line tool works. You need to import a key if it's not already in gpg's key ring then you need to select the recipient's key to use for encryption/decryption.

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

    If you did what I did and passed in the key as the recipient it doesn't work!

    It's not clear what this field is in either the GPG manual or PHP documentation which refers to this field as "fingerprint". Check gpg's key ring for your freshly imported key with:

    gpg --list-keys
    

    This will output something like this:

    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]
    

    This will give you the UID and on the second line the fingerprint associated with every key. As far as I can tell you can use the UID and fingerprint as the recipient.

    So your PHP code to encrypt might look like this:

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

    Then the recipient's code will look like this:

    // 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->affffdecryptkey('0DAA2C747B1974BE9EB9E6DCF7EE249AD00A46AA', '');
    echo $gpg->decrypt($encyptedMessage);
    

    Note the fingerprints are the same for both the recipient's public and private key.

    There is also a known issue with affffdecryptkey not taking a passphrase! You either need to remove the passphrase or change your version of GnuPG.

    0 讨论(0)
  • 2020-11-27 16:19

    Question 1: About PGP

    • PGP (Pretty Good Privacy) is a product and trademark of Symantec Corporation (they bought it some years ago).
    • OpenPGP is the standard used by PGP.
    • GnuPG (Gnu Privacy Guard) is a free and open source implementation of PGP.

    So what you want to do is encrypt to an OpenPGP key. Which implementation of OpenPGP your client uses to decrypt the data is not important for you. With PHP, commonly GnuPG is used and there are interfaces built-in.

    Question 2: Using GnuPG in PHP

    Use the GnuPG interface, which is an extension that can be installed for PHP.

    At first, import the key, where $keydata is the ASCII armored public key:

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

    Then use this key to encrypt the data, this time using the client's key's fingerprint:

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

    If you want to encrypt files, read and pass them to encrypt(). Be sure to use at least long key IDs (eg. DEADBEEFDEADBEEF), better fingerprints (as in the example) when referencing keys; and never use short key IDs (DEADBEEF), as those are vulnerable to collision attacks.


    The is a more comprehensive example for doing both added by a user in the PHP manual.

    0 讨论(0)
提交回复
热议问题