Encrypt files using PGP in PHP?

后端 未结 2 638
鱼传尺愫
鱼传尺愫 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.

提交回复
热议问题