Notifications Subscriptions API: Manage end-user subscriptions to email notifications triggered by the Bazaarvoice platform.
Decrypting Email Addresses
The Bazaarvoice Notifications Subscriptions API enables you to manage end-user subscriptions to email notifications triggered by the Bazaarvoice platform. To learn more, go to the Notifications Subscriptions API home page.
Contents
This page explains how to decrypt an email address returned by the Notifications Subscriptions API.
Introduction
To protect user privacy, email addresses will not be communicated in plain text. Instead, when responding to requests for opt-in or opt-out lists and in response to a successful submission, the Notifications Subscriptions API will send the email addresses in a format following the Advanced Encryption Standard (AES).
Email encryption details
AES is an NIST and US government approved standard for encrypting sensitive data based on the Rijndael algorithm. AES is a symmetrical algorithm (meaning it can be reversed using a shared key), offers a 128-bit block encryption and supports a shared key size of 128, 192, or 256 bits. It is also royalty free and supported by most major programming platforms.
Algorythm | AES |
---|---|
Key size | 128 bit |
Mode | ECB |
Padding | PKCS5/PKCS7 |
Decryption steps
Although every programming platform will vary in its implementation of AES, the following general steps will need to be performed to decipher an encrypted user email address:
- Hex decode encrypted email address string & shared secret key
- Initialize your decryption library using details above as appropriate
- Decrypt encrypted email address string
- Remove excess padding as necessary
Continue reading for code samples demonstrating user email address decryption.
Code samples
The follow code samples demonstrate how to decrypt the AES encrypted user email addresses returned by the Notifications Subscriptions API. Defer to your programming language's documentation for the exact implementation.
This code sample was created using Jave 8.
import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import javax.xml.bind.DatatypeConverter; import javax.crypto.spec.SecretKeySpec; import javax.crypto.BadPaddingException; import javax.crypto.NoSuchPaddingException; import javax.crypto.IllegalBlockSizeException; import java.security.NoSuchAlgorithmException; import java.security.InvalidKeyException; import java.security.NoSuchProviderException; // Example usage: $ java decrypt ENCRYPTED_EMAIL_FROM_BAZAARVOICE YOUR_SHARED_SECRET_KEY public class DecryptEmailExample { static public void main(String args[]) { // Hex decode the encrypted email byte[] encryptedEmailAddress = DatatypeConverter.parseHexBinary(args[0]); // Hex decode shared secret key byte[] sharedSecret = DatatypeConverter.parseHexBinary(args[1]); try { // http://docs.oracle.com/javase/8/docs/technotes/guides/security/SunProviders.html#SunJCEProvider Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding", "SunJCE"); SecretKeySpec key = new SecretKeySpec(sharedSecret, "AES"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] decrypted = cipher.doFinal(encryptedEmailAddress); System.out.println(new String(decrypted)); } catch (BadPaddingException e) { System.out.println(e); } catch (NoSuchPaddingException e) { System.out.println(e); } catch (IllegalBlockSizeException e) { System.out.println(e); } catch (NoSuchProviderException e) { System.out.println(e); } catch (NoSuchAlgorithmException e) { System.out.println(e); } catch (InvalidKeyException e) { System.out.println(e); } } }
This code sample was created using C# 6.0.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Cryptography; using System.IO; // Example usage: $ decrypt.exe ENCRYPTED_EMAIL_FROM_BAZAARVOICE YOUR_SHARED_SECRET_KEY namespace BazaarvoiceNotificationsApiExample { class Program { static void Main(string[] args) { // Hex decode the encrypted email byte[] bytEncryptedEmail = FromHex(args[0]); // Hex decode shared secret key byte[] bytSharedSecretKey = FromHex(args[1]); // Initialize encryption class var rijAlg = new RijndaelManaged(); rijAlg.KeySize = 128; rijAlg.Mode = CipherMode.ECB; rijAlg.Padding = PaddingMode.PKCS7; rijAlg.Key = bytSharedSecretKey; // Perform decryption string decrypted = Decrypt(rijAlg, bytEncryptedEmail); Console.Write(decrypted); Console.ReadLine(); } public static string Decrypt(RijndaelManaged rijAlg, byte[] bytEncryptedEmail) { using (var decryptor = rijAlg.CreateDecryptor()) { using (MemoryStream msDecrypt = new MemoryStream(bytEncryptedEmail)) { using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read)) { using (StreamReader srDecrypt = new StreamReader(csDecrypt)) { return srDecrypt.ReadToEnd(); } } } } } public static byte[] FromHex(string hex) { byte[] bytToken = new byte[hex.Length / 2]; for (int i = 0; i < hex.Length; i += 2) { bytToken[i / 2] = System.Convert.ToByte(hex.Substring(i, 2), 16); } return bytToken; } } }
This code sample was created using Node v4.4.
// Example usage: $ node decrypt.js ENCRYPTED_EMAIL_FROM_BAZAARVOICE YOUR_SHARED_SECRET_KEY // Requires https://github.com/evanvosberg/crypto-js var CryptoJS = require("crypto-js"); var args = process.argv.splice(2); // Hex decode the encrypted email var encryptedEmail = CryptoJS.enc.Hex.parse(args[0]); // Hex decode shared secret key var sharedSecretKey = CryptoJS.enc.Hex.parse(args[1]); // Initialize CryptoJS Arguments var config = { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.Pkcs7 }; var ciperParams = CryptoJS.lib.CipherParams.create({ ciphertext: encryptedEmail }); // Perform decryption var decrypted = CryptoJS.AES.decrypt(ciperParams, sharedSecretKey, config); console.log( decrypted.toString(CryptoJS.enc.Utf8) );
This code sample was created using Python 2.7.
# Example usage: $ python decrypt.py ENCRYPTED_EMAIL_FROM_BAZAARVOICE YOUR_SHARED_SECRET_KEY # Requires https://github.com/dlitz/pycrypto import sys from Crypto.Cipher import AES # Hex decode the encrypted email encryptedEmail = sys.argv[1].decode("hex") # Hex decode shared secret key sharedSecretKey = sys.argv[2].decode("hex") # Initialize Crypt_AES class cypher = AES.new(sharedSecretKey, AES.MODE_ECB) # Perform decryption decrypted = cypher.decrypt(encryptedEmail) print decrypted
This code sample was created using PHP 5.5.
<?php // Example usage: $ php decrypt.php ENCRYPTED_EMAIL_FROM_BAZAARVOICE YOUR_SHARED_SECRET_KEY // Requries https://github.com/phpseclib/phpseclib require_once(dirname(__FILE__) . '/phpseclib-1.0.5/phpseclib/Crypt/AES.php'); function hexToStr($hex){ $string = ''; for ($i = 0; $i < strlen($hex) - 1; $i += 2){ $string .= chr(hexdec($hex[$i].$hex[$i + 1])); } return $string; } // Hex decode the encrypted email $encryptedEmail = hexToStr($argv[1]); // Hex decode shared secret key $sharedSecretKey = hexToStr($argv[2]); // Initialize Crypt_AES class $cipher = new Crypt_AES(CRYPT_AES_MODE_ECB); $cipher->setKeyLength(128); $cipher->setKey($sharedSecretKey); // Perform decryption $decrypted = $cipher->decrypt($encryptedEmail); echo $decrypted . "\n";