Decrypting Email Address

Decryption steps

Email address can be retrieved from the following endpoints (Reviews, Review comments, Questions and Answers). To protect user privacy email addresses will be communicated in encrypted format.

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:

  1. Convert the secret key into bytes(UTF-8). Take 16 character key length of converted secret key and make Secretkeyspec with AES
  2. Decode the encrypted text with base64
  3. Decrypt Cipher with AES and the key
  4. Cipher do final to Convert into byte
  5. Convert the bytes to string and returns the decrypted email

Code samples

🚧

The code samples below are for educational purposes only.

The follow code samples demonstrate how to decrypt the AES encrypted user email addresses returned by the Conversation API. Refer to your programming language's documentation for the exact implementation.

//This code sample was created using Java 8.
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.util.Arrays;
import java.util.Base64;
import java.util.logging.Level;
import java.util.logging.Logger;
 
/**
 * Utility class which performs decryption of encrypted user emails
 */
public class DecryptEmailExample {
 
    private static final Logger LOGGER = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
    private static final String CIPHER = "AES/ECB/PKCS5PADDING";
    private static final String KEY_ALGO = "AES";
    private static SecretKey secretKey;
 
    public static String decrypt(final String encryptedText, final String secret) {
        try {
            SecretKeySpec keySpec = makeKey(secret);
            Base64.Decoder decoder = Base64.getDecoder();
            byte[] encryptedTextByte = decoder.decode(encryptedText);
            Cipher cipher = Cipher.getInstance(CIPHER);
            cipher.init(Cipher.DECRYPT_MODE, keySpec);
            byte[] decryptedByte = cipher.doFinal(encryptedTextByte);
            return new String(decryptedByte);
        } catch (Exception exception) {
            LOGGER.log(Level.SEVERE, "Error while decrypting: ", exception);
        }
        return null;
    }
 
    // Prepares a javax.crypto.SecretKey out of the provided secret key
    private static SecretKeySpec makeKey(final String secret)
    {
        SecretKeySpec secretKey = null;
        try {
            byte[] key = secret.getBytes(StandardCharsets.UTF_8);
            key = Arrays.copyOf(key, 16);
            secretKey = new SecretKeySpec(key, KEY_ALGO);
        } catch (Exception exception) {
            LOGGER.log(Level.SEVERE,"Error while secret key creation: ", exception);
        }
        return secretKey;
    }
    public static void main(String[] args) {
        decrypt("encryptedText","secretKey");
    }
}
//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;
 
 
    public static string Decrypt(string encryptedText, string secret)
    {
        using (var rijAlg = new RijndaelManaged())
        {
            rijAlg.Mode = CipherMode.ECB;
            rijAlg.Padding = PaddingMode.PKCS7;
            rijAlg.Key = MakeKey(secret);
            using (var decryptor = rijAlg.CreateDecryptor())
            {
                using (MemoryStream msDecrypt = new MemoryStream(Convert.FromBase64String(encryptedText)))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                           return srDecrypt.ReadToEnd();
                        }
                    }
                }
            }
        }
    }
    public static byte[] MakeKey(string key)
    {
        byte[] bytes = Encoding.UTF8.GetBytes(key);
        return bytes.Take(16).ToArray();
    }
//This code sample was created using Node v18.0.
const crypto = require('crypto');
const ciphertext = 'encrypted text'; // encrypted text
const ciphering = 'AES-128-ECB'; // encryption algorithm and mode
const saltkey = 'sharedsecretkey'; // shared secret key
 
function makeKey(saltkey) {
 return saltkey.slice(0, 16);
}
 
function decrypt(ciphertext,secretkey){
// Create the cipher object
    const decipher = crypto.createDecipheriv('aes-128-ecb', secretkey, '');
// Update the decipher with the ciphertext input
    let plaintext = decipher.update(ciphertext, 'base64', 'utf8');
// Finalize the decipher and append any remaining data
    plaintext += decipher.final('utf8');
    return plaintext;
}
 
secretkey = makeKey(saltkey);
plaintext = decrypt(ciphertext,secretkey);
 
// Print the decrypted plaintext
console.log(plaintext);
//This code sample was created using Python 3.
from base64 import b64decode
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import padding
from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes
 
UTF_8 = "utf-8"
SHARED_ENCODING_KEY = "secret key"
ENCRYPTED_TEXT = "encrypted text"
 
def make_aes_ecb_cipher(secret: str, key_size: int = 16) -> Cipher:
    """Makes the AES/ECB cipher using python stdlib packages.
    Args:
        secret (str): Shared secret
        key_size (int): Size of the key made using the secret
    Returns:
        Cipher: Returns the AES/ECB cipher for encryption/decryption
    """
    return Cipher(
        algorithms.AES(make_key(secret, key_size)),
        modes.ECB(),
        backend=default_backend(),
    )
def make_key(secret: str, key_size: int) -> str:
    """Create the key used for AES encryption/decryption using
    the shared secret.
    Args:
        secret (str): Shared secret
        key_size (int): Size of the key made using the secret
    Returns:
        str: Key used for AES encryption/decryption
    """
    if key_size <= 0:
        AssertionError("key_size cannot be <=0.")
return secret.encode(UTF_8)[:key_size]
 
def decrypt_from_base64(encrypted_text: str, secret: str, key_size: int) -> str:
    """Decrypts base64 encoded encrypted text using AES/ECB/PKCS5 to plain text.
    Args:
        encrypted_text (str): Base64 encoded encrypted text
        secret (str): Shared secret
        key_size (int): Size of the key made using the secret
    Returns:
        str: Encrypted text using AES/ECB/PKCS5 encryption in base64
    """
    encrypted_bytes = b64decode(encrypted_text)
    cipher = make_aes_ecb_cipher(secret, key_size)
    decryptor = cipher.decryptor()
    padded_bytes = decryptor.update(encrypted_bytes) + decryptor.finalize()
    unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder()
    unpadded_bytes = unpadder.update(padded_bytes) + unpadder.finalize()
    return unpadded_bytes.decode(UTF_8)
 
print(decrypt_from_base64(ENCRYPTED_TEXT, SHARED_ENCODING_KEY, 16))
//This code sample was created using PHP 5.5
<!--?php
function makeKey($key) {
    return substr($key, 0, 16);
}
 
// Store the cipher method - AES/ECB/PKCS5PADDING
$ciphering = "AES-128-ECB";
 
// Encrypted text and shared secret key here
$encryptedtext = "encrypted text";
$saltkey= "sharedsecretkey";
// make secret key from salt
$secretkey = makeKey($saltkey);
 
// Use openssl_decrypt() function to decrypt the data
$decrypted = openssl_decrypt($encryptedtext, $ciphering, $secretkey);
 
echo $decrypted . "\n";
?-->