This is a great library! I've started using it in some of my little projects. Unfortunately, it only supports signing with SHA-1, which is now deprecated in favor of SHA-256 (see RFC 6376). I've updated the code to default to using SHA-256 instead. Only a few lines need to be changed in the class file.
Firstly, I created a new options and default_options value called dkim_hash, which defaults to sha256:
$default_options = array(
[...]
/*
* Specify whether to sign with SHA-256 (recommended) or the older, weaker SHA-1.
* This variable takes either the value "sha1" or "sha256", as those are the only
* two algorithms supported by the current version of DKIM.
*/
'dkim_hash' => 'sha256'
[...]
)
Then, in _get_dkim_header(), I've made three changes:
I've replaced the call to sha1() with a call to hash(). This supports either algorithm natively.
The algorithm value in the DKIM-Signature header now reflects which hash we're using (rsa-sha1 or rsa-sha256).
I use the fourth parameter to openssl_sign() to specify the appropriate algorithm by passing either the constant OPENSSL_ALGO_SHA1 or OPENSSL_ALGO_SHA256.
private function _get_dkim_header($body){
$body =
($this -> options['dkim_body_canonicalization'] == 'simple') ?
$this -> _dkim_canonicalize_body_simple($body) :
$this -> _dkim_canonicalize_body_relaxed($body);
// Base64 of packed binary hash of body
$bh = rtrim(chunk_split(base64_encode(pack("H*", hash($this->options['dkim_hash'],$body))), 64, "\r\n\t"));
$i_part =
($this -> options['identity'] == null) ?
'' :
' i='.$this -> options['identity'].';'."\r\n\t";
$dkim_header =
'DKIM-Signature: '.
'v=1;'."\r\n\t".
'a=rsa-' . $this -> options['dkim_hash'] . ';'."\r\n\t".
'q=dns/txt;'."\r\n\t".
's='.$this -> selector.';'."\r\n\t".
't='.time().';'."\r\n\t".
'c=relaxed/'.$this -> options['dkim_body_canonicalization'].';'."\r\n\t".
'h='.implode(':', array_keys($this -> canonicalized_headers_relaxed)).';'."\r\n\t".
'd='.$this -> domain.';'."\r\n\t".
$i_part.
'bh='.$bh.';'."\r\n\t".
'b=';
// now for the signature we need the canonicalized version of the $dkim_header
// we've just made
$canonicalized_dkim_header = $this -> _dkim_canonicalize_headers_relaxed($dkim_header);
// we sign the canonicalized signature headers
$to_be_signed = implode("\r\n", $this -> canonicalized_headers_relaxed)."\r\n".$canonicalized_dkim_header['dkim-signature'];
// $signature is sent by reference in this function
$signature = '';
$signing_algorithm = null;
if ($this->options['dkim_hash'] === 'sha256') {
$signing_algorithm = OPENSSL_ALGO_SHA256;
} else if ($this->options['dkim_hash'] === 'sha1') {
$signing_algorithm = OPENSSL_ALGO_SHA1;
} else {
die('Unsupported dkim_hash value "' . $this->options['dkim_hash'] . '" -- DKIM only supports sha256 and sha1.');
}
if(openssl_sign($to_be_signed, $signature, $this -> private_key, $signing_algorithm)){
$dkim_header .= rtrim(chunk_split(base64_encode($signature), 64, "\r\n\t"))."\r\n";
}
else {
trigger_error(sprintf('Could not sign e-mail with DKIM : %s', $to_be_signed), E_USER_WARNING);
$dkim_header = '';
}
return $dkim_header;
}
I've also done the same to the _get_dk_header() function.
This is a great library! I've started using it in some of my little projects. Unfortunately, it only supports signing with SHA-1, which is now deprecated in favor of SHA-256 (see RFC 6376). I've updated the code to default to using SHA-256 instead. Only a few lines need to be changed in the class file.
Firstly, I created a new options and default_options value called dkim_hash, which defaults to sha256:
Then, in _get_dkim_header(), I've made three changes:
I've also done the same to the _get_dk_header() function.
Hope this helps!