OpenPGP Mail
WordPress plugin for OpenPGP implementation
by Khairil Zhafri · github.com/khrlzhfr/openpgp-mail · website
Install
No release zip yet. The repository archive installs, but the folder name will carry the branch suffix and updates will not flow:
wp plugin install https://github.com/khrlzhfr/openpgp-mail/archive/refs/heads/main.zipOpenPGP Mail for WordPress
Send end-to-end encrypted emails from WordPress using OpenPGP.
Description
OpenPGP Mail for WordPress allows your site to send encrypted emails to recipients who have PGP public keys. The plugin automatically fetches public keys from multiple sources:
- WordPress user meta – Keys stored in user profiles
- Proton Mail API – For Proton Mail addresses (protonmail.com, proton.me, pm.me)
- Mailvelope Key Server – Keys uploaded via the Mailvelope browser extension
- keys.openpgp.org – The OpenPGP keyserver
If no public key is found, emails can optionally be sent unencrypted (configurable).
Requirements
- WordPress 5.8 or later
- PHP 7.4 or later
Installation
- Download or clone this repository to your
wp-content/plugins/directory - Navigate to the plugin directory and install dependencies:
cd wp-content/plugins/openpgp-mail composer install - Activate the plugin through the WordPress admin
Configuration
Navigate to Settings → OpenPGP Mail to configure:
- Public key sources – Enable or disable individual key sources
- Fallback behaviour – Whether to send unencrypted if no key is found
- Cache duration – How long to cache fetched public keys
Usage
Basic usage
Replace calls to wp_mail() with openpgp_mail():
openpgp_mail(
'recipient@example.com',
'Subject',
'Message body'
);
Full signature
openpgp_mail(
$to, // string|array - Recipient email(s)
$subject, // string - Email subject
$message, // string - Email body
$headers, // string|array - Optional headers
$attachments, // string|array - Optional attachment paths
$pubkey // string|null - Optional public key (skips lookup)
);
Helper functions
// Get public key for an email
$pubkey = openpgp_get_pubkey('user@example.com');
// Validate a public key
$is_valid = openpgp_validate_pubkey($pubkey);
// Check if email is Proton Mail
$is_proton = openpgp_is_proton_mail('user@proton.me');
// Clear cached key for an email
openpgp_clear_pubkey_cache('user@example.com');
// Check if OpenPGP library is available
$available = openpgp_is_library_available();
Action hooks
// Fired when falling back to unencrypted
add_action('openpgp_mail_fallback_unencrypted', function($email) {
// Log or handle fallback
});
// Fired when encryption fails
add_action('openpgp_mail_encryption_failed', function($email, $error) {
// Log error
}, 10, 2);
// Fired when sending with unencrypted attachments
add_action('openpgp_mail_unencrypted_attachments', function($email, $attachments) {
// Warn about unencrypted attachments
}, 10, 2);
// Fired before/after sending
add_action('openpgp_mail_before_send', function($email) {});
add_action('openpgp_mail_after_send', function($email, $result) {}, 10, 2);
User profiles
Users can add their PGP public key via their WordPress profile page. The key will be used automatically when sending emails to that user's address.
Limitations
- Attachments are not encrypted – Only the message body is encrypted. For full security, consider alternative approaches for sensitive attachments.
- Single recipient key lookup – When sending to multiple recipients, only the first recipient's key is used.
Security considerations
- Keys fetched from external servers are cached to reduce lookups
- Failed lookups are cached for 1 hour to prevent repeated failed requests
- User-provided keys are validated before storage
- All external requests use HTTPS
Changelog
1.0.0
- Initial release
Licence
GPL v2 or later. See LICENSE.