Creating the Email Authentication Token

This page explains how to create an email address message authentication code (MAC) for submission to the Bazaarvoice platform using the Notifications Subscriptions API.

Introduction

The email authentication token is a message authentication code (MAC) with the email address as the message. Creating a MAC allows Bazaarvoice to verify the email address comes from a trusted source. You create a MAC using the email address and a secret key only known to you and Bazaarvoice. We are able to verify your email authentication token by creating our own MAC and comparing the two. If they match we know the email authentication token came from a trusted source.

The email authentication token is used when submitting an email address to a notification opt-in or opt-out list. This two step process involves:

  1. Create an email authentication token
  2. Add the token to an opt-out list or opt-in list.

Continue reading to learn how to perform step #1.

Email authentication token algorithm

The email authentication token is a UTF-8 string consisting of the user email address obfuscated using a cryptographic hash function and then concatenated to a hex encoded version of the email address.

Perform the following steps using your shared secret key to create the email authentication token:

  1. Generate a hex encoded HMAC_SHA256 hash of the email address (this should be 64 characters long)
  2. Hex encode the user email address
  3. Append the results of step 2 to the end of step 1

Pseudo-code implementation

This pseudo-code demonstrates how to create an email authentication token. Defer to your programming environment's documentation for the exact implementation.

userEmail = utf8_encode("[email protected]")
sharedKey = utf8_encode("YOUR_SHARED_SECRET_KEY")
emailAuthToken = hmac_sha256(sharedKey, userEmail) + hex(userEmail)

🚧

Use HTTPS to submit email authentication tokenThe nature of a MAC is that the message (the email address) must be communicated in an accessible way — hex(userEmail) above. To ensure the security of the email address you should always perform submissions to the Notifications Subscriptions API using HTTPS.

Verification values

Use the following values to verify your implementation:

User Email: "[email protected]"
Shared Secret Key: "90246e8fbffef8851179f4a33f2de691"

If your implementation is correct, the resulting email authentication token (with the first 64 characters highlighted) will be the following:

3e2246ee4315c7e3a60326ab171e63a1191887037cbaf6e1a2c4176d743fe76d7061742e736d697468406578616d706c652e636f6d

Code samples

📘

The code samples below are for educational purposes only. They are not intended to be used in a production environment and are provided "as is" without warranty of any kind.

The following code samples demonstrate how to encrypt the access signature. Defer to your programming language's documentation for the exact implementation.

// Usage: 
// 1. path/to/file$ javac EmailAuthTokenExample.java 
// 2. path/to/file$ java EmailAuthTokenExample "emailAddress" "sharedSecret" 

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import org.apache.commons.codec.binary.Hex;

public class EmailAuthTokenExample  {
    public static void main(String[] args) throws Exception {
        String emailAddress = args[0];
        String sharedSecret = args[1];
        String digest = null;
        String emailAuthToken = null;

        try {
            SecretKeySpec key = new SecretKeySpec(sharedSecret.getBytes("UTF-8"), "HmacSHA256");
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(key);
            byte[] bytes = mac.doFinal(emailAddress.getBytes("UTF-8"));
            digest = DatatypeConverter.printHexBinary(bytes);

            emailAuthToken = digest.toLowerCase() + toHex(emailAddress);
        }
        catch (UnsupportedEncodingException e) {} catch (InvalidKeyException e) {} catch (NoSuchAlgorithmException e) {}
    }

    public static String toHex(String arg) throws Exception {
        return Hex.encodeHexString(arg.getBytes());
    }
}
// Usage: 
// 1. path\to\> csc EmailAuthTokenExample.cs 
// 2. path\to\> EmailAuthTokenExample.exe "emailAddress" "sharedSecret" 
using System;
using System.Text;
using System.Security.Cryptography;
public class EmailAuthTokenExample {
    static void Main(string[] args) {
        string emailAddress = args[0];
        string key = args[1];
        string digest = null;
        string emailAuthToken = null;
        var hmac = new HMACSHA256(UTF8Encode(key));
        byte[] bytes = hmac.ComputeHash(UTF8Encode(emailAddress));
        digest = HexEncode(bytes);
        emailAuthToken = digest + HexEncode(UTF8Encode(emailAddress));
        Console.WriteLine(emailAuthToken.ToLower());
    }
    public static byte[] UTF8Encode(string text) {
        var encoding = new UTF8Encoding();
        return encoding.GetBytes(text);
    }
    public static string HexEncode(byte[] bytes) {
        return BitConverter.ToString(bytes).Replace("-", "");
    }
}
// Usage: path/to/file$ node EmailAuthTokenExample.js "emailAddress" "sharedSecret" 
var crypto = require('crypto');
var emailAddress = new Buffer(process.argv[2], "utf8");
var sharedSecret = new Buffer(process.argv[3], "utf8");
var hmac = crypto.createHmac('sha256', sharedSecret).update(emailAddress);
var digest = hmac.digest('hex');
console.log(digest + emailAddress.toString('hex'))
#Usage: path / to / file$ python EmailAuthTokenExample.py "emailAddress" "sharedSecret"
import sys
import hmac
import hashlib 
emailAddress = unicode(sys.argv[1], 'utf-8') 
sharedSecret = unicode(sys.argv[2], 'utf-8') 
digest = hmac.new(sharedSecret.encode('utf-8'), emailAddress.encode('utf-8'), hashlib.sha256).hexdigest() 
print digest + emailAddress.encode('hex')
 <?php
 // usage: path/to/file$  php EmailAuthTokenExample.php "emailAddress" "sharedSecret"

 // utf8_encode() assumes input is ISO-8859-1 encoded. Your implementation may
 // require a different technique.
 $emailAddress = utf8_encode($argv[1]);
 $sharedSecret = utf8_encode($argv[2]);

 $digest = hash_hmac("sha256", $emailAddress, $sharedSecret);
 echo $digest . bin2hex($emailAddress) . "\n";