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 = "firstname.lastname@example.org"; // random gmail or yahoo test account $myAddress = "email@example.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...)
(...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!