I’m sending an email with an attachment from one server to another server and I would like to find a good way to verify that this email really comes from that server.
The applications are in PHP. I can’t verify the origin with for example the IP (server in an Intranet). Could I use a hash in subject or in the body of the email.
Advertisement
Answer
Generating a hash alone is not enough. What you need is asymmetric cryptography. The first step to implementing this would be to generate a public/private key pair. This is easily accomplished using openssl.
openssl genrsa -out private.key 1024 openssl rsa -in private.key -pubout > public.key
In the message sending script :
- Generate a hash from the attachment.
- Use the private key to generate a signature from the hash.
- Add the signature to the email as a custom header.
For example:
<?php $hash = hash_file("md5", "path/to/your.file"); $key = openssl_pkey_get_private("file://path/to/your/private.key"); openssl_sign($hash, $signature, $key); openssl_free_key($key); // build your message and attach the file $headers['X-Signature'] = base64_encode($signature); mail($to, $subject, $message, $headers); ?>
In the message reading script :
- Parse the email file (which is beyond the scope of this question, there are other answers explaining how)
- Use the public key to check the validity of the signature.
Something like this:
<?php require_once('email-parser.php'); $msg = parse_email_file("path/to/your/message.eml"); $signature = base64_decode($msg['headers']['X-Signature']); $hash = md5($msg['attachment']); $key = openssl_pkey_get_public("file://path/to/your/public.key"); $verified = openssl_verify($hash, $signature, $key); openssl_free_key($key); if ($verified) { // DO STUFF } else { // PANIC!!! } ?>