Here's my code:
Code: Select all
<?php
// initialize key
$privatePem = "-----BEGIN RSA PRIVATE KEY-----
MIII5RV/0k9USo...etc...hXF2Vh7T4yfT5QN
-----END RSA PRIVATE KEY-----";
$encKey = @openssl_pkey_get_private( $privatePem );
if (!$encKey) die("Unable to extract encryption key");
// setup email message
$to = "example@gmail.com"; // random gmail or yahoo test account
$myAddress = "myname@mydomain.com";
$subject = "Hello";
$body = "Hi, this is a test message";
$fromHeader = "From: $myAddress";
// create canonicalizated message (using 'simple' convention)
$canonLines = array();
$canonLines[] = $fromHeader;
$canonLines[] = ""; // the empty line between headers and body
$canonLines[] = $body; // body just consists of one line here (with no line-ending)
$crlf = "\r\n";
$canonTxt = implode($crlf,$canonLines).$crlf;
// create checksum
$hexHash = sha1($canonTxt); // this is for php4 compatibility,
$rawHash = pack('H*',$hexHash); // with php5 we can simply do sha1($txt,true) to get binary result
// encrypt + encode
if (!@openssl_private_encrypt( $rawHash, $encryptedHash, $encKey )) die("Unable to encrypt hash");
$dkey = base64_encode($encryptedHash);
// setup custom headers
$headers = "DomainKey-Signature: a=rsa-sha1; s=mail; d=mydomain.com; h=From; q=dns; c=simple; b=$dkey;\n";
$headers .= "$fromHeader\n";
// send mail
$success = mail( $to , $subject , $body , $headers );
die( $success ? "mail sent" : "mail NOT sent" );
?>
Unfortunately, when I send a mail like this, both gmail and yahoo report domainkeys = bad or fail (bad sig).
Note that I included the h=From in the signature on purpose. Since PHP mail() and my provider's SMTP server will both add additional headers (which I can't take along in my signature checksum) I want to explicitly use only a header I can calculate. So in the end, the complete mail will look something like this:
and by using only the From: header I can make sure in advance what the canonicalizated message (on which the DomainKeys signature is calced) needs to be.(...some headers...)
DomainKey-Signature: blablabla
From: my@address
(...some more headers...)
Body consisting of one line
If anybody knows how DomainKeys works and can see what I'm doing wrong, you'd definitely make my day!
