Sign S/MIME Email with PHPMailer

PHPMailer can add an S/MIME digital signature when you provide a PEM certificate, its matching private key, the key passphrase, and—when required—the intermediate certificate chain. The sender address should match the email identity in the signing certificate.

Last updated: October 5, 2026.

<?php
use PHPMailerPHPMailerPHPMailer;

require __DIR__ . '/vendor/autoload.php';

$certificate = __DIR__ . '/secrets/signer.crt';
$privateKey = __DIR__ . '/secrets/signer.key';
$certificateChain = __DIR__ . '/secrets/chain.pem';
$passphrase = getenv('SMIME_KEY_PASSPHRASE') ?: '';

$certificatePem = file_get_contents($certificate);
$privateKeyPem = file_get_contents($privateKey);
if (!openssl_x509_check_private_key($certificatePem, [$privateKeyPem, $passphrase])) {
    throw new RuntimeException('The certificate and private key do not match.');
}

$mail = new PHPMailer(true);
$mail->setFrom('[email protected]', 'Example Sender');
$mail->addAddress('[email protected]');
$mail->Subject = 'Signed message';
$mail->Body = 'This message is digitally signed.';
$mail->sign($certificate, $privateKey, $passphrase, $certificateChain);
$mail->send();

Keep the private key outside the public web directory and load its passphrase from protected configuration rather than source code. The optional fourth argument supplies intermediate CA certificates so a recipient can build the trust chain to a root it already trusts.

Check identity, validity, and key pairing

A signature may be cryptographically correct yet shown as invalid or untrusted when the certificate is expired, the sender address differs from the certificate identity, an intermediate certificate is missing, or the recipient does not trust the issuing CA. PHP’s openssl_x509_check_private_key() reference documents the pairing test used above. Inspect validity dates and the subject with openssl_x509_parse().

Sign only after the message is complete

Configure recipients, body, alternatives, and attachments before sending. PHPMailer applies signing while it builds the final MIME message. Its official S/MIME signing example shows the certificate, private key, passphrase, and chain arguments; the sign() API reference defines them.

S/MIME signing proves message integrity and signer identity; it does not encrypt the body. For related email setup, see sending through SMTP with PHPMailer, attachments and inline images, and email delivery troubleshooting.

Related Web Cheat Sheet guides

Sergey Kornilov

Sergey Kornilov