\JVconseil\DkimPhpMailSignatureDKIMsign

Stand-alone DKIM class to sign email with a 2048 bit private key hashed with SHA-256 algorithm.

Usage

Sample lines to import into your mail code to start signing with DKIM:

require_once __DIR__ . '/../vendor/autoload.php' ; // Autoload files using Composer autoload
use JVconseil\DkimPhpMailSignature\DKIMsign ;
use JVconseil\DkimPhpMailSignature\DKIMconfig ;

// init
$config = new DKIMconfig('/www/inc/config/jv-conseil/dkim-php-mail-signature/config.inc.php') ;
$sign = new DKIMsign(
$config->private_key,
$config->passphrase,
$config->domain,
$config->selector) ;

// sign
$signed_headers = $sign->get_signed_headers($to, $subject, $message, $headers) ;

// send email
mail($to, $subject, $message, $signed_headers.$headers) ;

Test Examples in Terminal

In Terminal enter this command line to start testing examples:

php ~/dkim-php-mail-signature/examples/SignSimple.php

Sponsorship

If this project helps you reduce time to develop, you can give me a cup of coffee ☕️ :-)

Donate with PayPal

Examples

Simple example with config file accessed through a var:

<?php
/**
 * Simple example test with config file accessed through a var.
 *
 * To test this example enter in Terminal this command line:
 * ```
 * php ~/dkim-php-mail-signature/examples/SignSimple.php
 * ```
 *
 * @author JV conseil — Internet Consulting <contact@jv-conseil.net>
 * @see http://www.jv-conseil.net
 * @see https://github.com/JV-conseil-Internet-Consulting/dkim-php-mail-signature
 * @see https://packagist.org/packages/jv-conseil/dkim-php-mail-signature
 * @license EUPL-1.2 license, Copyright (c) 2019-2023 JV conseil – Internet Consulting, All rights reserved.
 * @version v1.2.5
 */


/** Call Composer Package JVconseil\DkimPhpMailSignature */
require_once __DIR__ . '/../vendor/autoload.php' ; // Autoload files using Composer autoload

use JVconseil\DkimPhpMailSignature\DKIMsign ;

/** @var string $config after setting up the config file and your DNS records :*/
$config = include_once(__DIR__ . '/../config/config.sample.inc.php') ;


// YOUR E-MAIL
$to = 'recipient@' . $config['domain'] ;

$subject = 'DKIM e-mail test for domain ' . $config['domain'] ;

$headers =
'MIME-Version: 1.0
From: "Sender" <sender@' . $config['domain'] . '>
Content-type: text/html; charset=utf8';

$message =
'<html>
	<header></header>
	<body>
		Hello, this a DKIM e-mail test
	</body>
</html>';


// Make sure linefeeds are in CRLF format - it is essential for signing
$message = preg_replace('/(?<!\r)\n/', "\r\n", $message) ;
$headers = preg_replace('/(?<!\r)\n/', "\r\n", $headers) ;


// 1) YOU USUALLY DID :
// mail($to, $subject, $message, $headers);


// 2) NOW YOU WILL DO (you can use options to add some flavor) :

$options = array(
	'use_dkim' => false,
	'use_domainKeys' => true,
	'identity' => $config['identity'],
	// if you prefer simple canonicalization (though the default "relaxed"
	// is recommended)
	'dkim_body_canonicalization' => 'simple',
	'dk_canonicalization' => 'nofws',
	// if you want to sign the mail on a different list of headers than the
	// default one (see class constructor). Case-insensitive.
	'signed_headers' => array(
		'message-Id',
		'Content-type',
		'To',
		'subject'
	)
);

$signature = new DKIMsign(
	// $options,
	$config['private_key'],
	$config['passphrase'],
	$config['domain'],
	$config['selector']
);

$signed_headers = $signature -> get_signed_headers($to, $subject, $message, $headers) ;

try {
	if (mail($to, $subject, $message, $signed_headers.$headers) == true) {
		// header('Content-Type: text/plain') ;
		header('Content-Type: text/plain') ;
		echo $signed_headers . $headers . "\r\n" ;
		echo 'To: ' . $to . "\r\n" ;
		echo 'Subject: ' . $subject . "\r\n" ;
		echo $message . "\r\n" ;
	}
} catch (Exception $e) {
    die('Caught exception: ' . $e->getMessage() . "\r\n") ;
}

Class example with config file accessed through a class:

<?php
/**
 * Class example with config file accessed through a class.
 *
 * To test this example enter in Terminal this command line:
 * ```
 * php ~/dkim-php-mail-signature/examples/SignWithConfigClass.php
 * ```
 *
 * @author JV conseil — Internet Consulting <contact@jv-conseil.net>
 * @see http://www.jv-conseil.net
 * @see https://github.com/JV-conseil-Internet-Consulting/dkim-php-mail-signature
 * @see https://packagist.org/packages/jv-conseil/dkim-php-mail-signature
 * @license EUPL-1.2 license, Copyright (c) 2019-2023 JV conseil – Internet Consulting, All rights reserved.
 * @version v1.2.5
 */


 /** Call Composer Package JVconseil\DkimPhpMailSignature */
require_once __DIR__ . '/../vendor/autoload.php' ; // Autoload files using Composer autoload

use JVconseil\DkimPhpMailSignature\DKIMsign ;
use JVconseil\DkimPhpMailSignature\DKIMconfig ;


/** @var string $config after setting up the config file and your DNS records :*/
$config = new DKIMconfig(__DIR__ . '/../config/config.sample.inc.php') ;

// YOUR E-MAIL
$to = 'recipient@' . $config->domain ;

$subject = 'DKIM e-mail test for domain ' . $config->domain ;

$headers =
'MIME-Version: 1.0
From: "Sender" <sender@' . $config->domain . '>
Content-type: text/html; charset=utf8' ;

$message =
'<html>
	<header></header>
	<body>
		Hello, this a DKIM e-mail test
	</body>
</html>';


// Make sure linefeeds are in CRLF format - it is essential for signing
$message = preg_replace('/(?<!\r)\n/', "\r\n", $message) ;
$headers = preg_replace('/(?<!\r)\n/', "\r\n", $headers) ;


// 1) YOU USUALLY DID :
// mail($to, $subject, $message, $headers);


// 2) NOW YOU WILL DO (you can use options to add some flavor) :

$options = array(
	'use_dkim' => false,
	'use_domainKeys' => true,
	'identity' => $config->identity,
	// if you prefer simple canonicalization (though the default "relaxed"
	// is recommended)
	'dkim_body_canonicalization' => 'simple',
	'dk_canonicalization' => 'nofws',
	// if you want to sign the mail on a different list of headers than the
	// default one (see class constructor). Case-insensitive.
	'signed_headers' => array(
		'message-Id',
		'Content-type',
		'To',
		'subject'
	)
);

$sign = new DKIMsign(
	$config->private_key,
	$config->passphrase,
	$config->domain,
	$config->selector
	// $options
);

$signed_headers = $sign->get_signed_headers($to, $subject, $message, $headers) ;

try {
	if (mail($to, $subject, $message, $signed_headers.$headers) == true) {
		// header('Content-Type: text/plain') ;
		echo $signed_headers . $headers . "\r\n" ;
		echo 'To: ' . $to . "\r\n" ;
		echo 'Subject: ' . $subject . "\r\n" ;
		echo $message . "\r\n" ;
	}
} catch (Exception $e) {
    die('Caught exception: ' . $e->getMessage() . "\r\n") ;
}

Summary

Methods
Properties
Constants
__construct()
get_signed_headers()
No public properties found
No constants found
No protected methods found
No protected properties found
N/A
_dkim_canonicalize_headers_relaxed()
_dkim_canonicalize_body_simple()
_dkim_canonicalize_body_relaxed()
_dk_canonicalize_simple()
_dk_canonicalize_nofws()
_get_dkim_header()
_get_dk_header()
$private_key
$domain
$selector
$options
$canonicalized_headers_relaxed
N/A

Properties

$private_key

$private_key : string

Type

string — Provide your 2048 bit private key generated in Terminal with command line: ```openssl genrsa -des3 -out private.pem 2048```

$domain

$domain : string

Type

string — is your domain name e.g.: google.com

$selector

$selector : string

Type

string — is your selector DNS DKIM record e.g.: selector._domainkey.google.com.

$options

$options : array

Type

array

$canonicalized_headers_relaxed

$canonicalized_headers_relaxed : 

Type

Methods

__construct()

__construct(  $private_key,   $passphrase,   $domain,   $selector,   $options = array()) 

Parameters

$private_key
$passphrase
$domain
$selector
$options

get_signed_headers()

get_signed_headers(  $to,   $subject,   $body,   $headers) 

You may leave $to and $subject empty if the corresponding headers are already in $headers

Parameters

$to
$subject
$body
$headers

_dkim_canonicalize_headers_relaxed()

_dkim_canonicalize_headers_relaxed(  $sHeaders) 

This function returns an array of relaxed canonicalized headers (lowercases the header type and cleans the new lines/spaces according to the RFC requirements).

only headers required for signature (specified by $options) will be returned the result is an array of the type : array(headerType => fullHeader [, ...]), e.g. array('mime-version' => 'mime-version:1.0')

Parameters

$sHeaders

_dkim_canonicalize_body_simple()

_dkim_canonicalize_body_simple(  $body) 

Apply RFC 4871 requirements before body signature. Do not modify

Parameters

$body

_dkim_canonicalize_body_relaxed()

_dkim_canonicalize_body_relaxed(  $body) 

Apply RFC 4871 requirements before body signature. Do not modify

Parameters

$body

_dk_canonicalize_simple()

_dk_canonicalize_simple(  $body,   $sHeaders) 

Apply RFC 4870 requirements before body signature. Do not modify

Parameters

$body
$sHeaders

_dk_canonicalize_nofws()

_dk_canonicalize_nofws(  $body,   $sHeaders) 

Apply RFC 4870 requirements before body signature. Do not modify

Parameters

$body
$sHeaders

_get_dkim_header()

_get_dkim_header(  $body) 

The function will return no DKIM header (no signature) if there is a failure, so the mail will still be sent in the default unsigned way it is highly recommended that all linefeeds in the $body and $headers you submit are in the CRLF (\r\n) format !! Otherwise signature may fail with some MTAs

Parameters

$body

_get_dk_header()

_get_dk_header(  $body,   $sHeaders) 

Parameters

$body
$sHeaders