Email Encryption

For additional security, it is possible to encrypt Advocate and Friend e-mails on back-end. This can be done by using 2048-bit key Talkable Public Key. So, instead of sending email addresses in plain text, you can send them encrypted.

Passing email as a GET parameter to Standalone Campaign

Also it’s possible to pass encrypted email as a GET parameter (e.g. for CTA links that point to standalone invite page). But to do that encrypted email should be URL-encoded.

Ruby Example

require 'openssl'
require 'base64'

def key
  @key ||= begin
    key_content ='talkable_public_key.pem')

def encode_email_for_talkable(email)
  encrypted_email = key.public_encrypt(email)

puts encode_email_for_talkable("")

Java Example

This example uses Bouncy Castle library and has been tested on:

  • bcprov-jdk15on-156.jar (Provider)
  • bcpkix-jdk15on-156.jar (PKIX/CMS/EAC/PKCS/OCSP/TSP/OPENSSL)

that can be downloaded from Bouncy Castle Latest Releases.


Please note that loading a Security Provider and a key into memory takes more time than encrypting. So it is recommended to store the key in memory instead of loading it each time to avoid performance overhead.

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import java.util.Base64;

import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;

public class EncryptionDemo {
    static class EmailEncryptor {
        private Cipher cipher;
        private Key publicKey;

        private void initPublicKey() throws IOException {
            PEMParser pemParser = new PEMParser(new FileReader("talkable_public_key.pem"));
            JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
            SubjectPublicKeyInfo publicKeyInfo = (SubjectPublicKeyInfo) pemParser.readObject();
            publicKey = converter.getPublicKey(publicKeyInfo);

        private void initCipher() throws GeneralSecurityException {
            cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
            cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        public EmailEncryptor() throws IOException, GeneralSecurityException {

        public String encryptEmail(String email) throws BadPaddingException, IllegalBlockSizeException {
            byte[] input = email.getBytes();
            byte[] cipherText = cipher.doFinal(input);
            byte[] encodedBytes = Base64.getEncoder().encode(cipherText);
            return new String(encodedBytes);

    static EmailEncryptor emailEncryptor;

    static {
        Security.addProvider(new BouncyCastleProvider());
        try {
            emailEncryptor = new EmailEncryptor();
        } catch (IOException | GeneralSecurityException e) {

    public static String encryptEmail(String email) throws BadPaddingException, IllegalBlockSizeException {
        return emailEncryptor.encryptEmail(email);

    public static void main(String[] args) throws Exception {
        String email = "";

Front-end Part

Please modify the front-end using this pseudo code example:

 _talkableq.push(['authenticate_customer', {
   email: '<%= to_json(TalkableEmail.encrypt( %>',
   first_name: '<%= to_json(current_user.first_name) %>',
   last_name: '<%= to_json(current_user.last_name) %>'