ePrivacy and GPDR Cookie Consent by Cookie Consent Skip to main content

Hashing and Encrypting PII data

This guide explains how to properly implement hashing and encryption for PII data before it reaches Meiro CDP, ensuring compliance with privacy requirements while maintaining functionality for identity resolution and activation.

Overview

To fulfill CDP requirements while limiting PII data exposure, implement a dual approach:

  1. Hashing - For identity resolution and advertising platform activation
  2. Encryption - For secure transmission to destination systems

Prerequisites

  • Access to Meiro Events Web SDK
  • Understanding of JavaScript hashing and encryption
  • Public/private key pair for RSA encryption

Hashing Implementation

Requirements

  • Send Client ID from all sources when possible
  • Hash PII data using consistent sanitization and algorithms across all sources
  • Follow advertising platform requirements (Meta, Google, etc.)

Standardized Process

Use the following sanitization and hashing approach for all sources:

  1. Email sanitization: lowercase + trim whitespace
  2. Phone sanitization: remove symbols, leading zeros, spaces, include country code
  3. Hashing algorithm: SHA256

Implementation Example

// Email hashing
const email = "Kurka.Vojtech@gmail.com";
const sanitizedEmail = email.toLowerCase().trim();
const emailHash = await crypto.subtle.digest('SHA-256', 
  new TextEncoder().encode(sanitizedEmail)
);

// Phone hashing
const phone = "+420 606 199 831";
const sanitizedPhone = "420606199831"; // Remove symbols, spaces, leading zeros
const phoneHash = await crypto.subtle.digest('SHA-256', 
  new TextEncoder().encode(sanitizedPhone)
);

Common Mistakes to Avoid

Inconsistent sanitization:

  • Source A: Kurka.Vojtech@gmail.com → Different hash
  • Source B: kurka.vojtech@gmail.com → Different hash

Different algorithms:

  • Source A: SHA256
  • Source B: MD5

Correct approach: Same sanitization + same algorithm = consistent hashes

Encryption Implementation

RSA Encryption Setup

For scenarios requiring raw PII in destination systems while maintaining CDP security:

  1. Public key: Distributed to data sources for encryption
  2. Private key: Available only in destination system for decryption

JavaScript Implementation

// RSA encryption using Web Crypto API
async function encryptWithRSA(data, publicKey) {
  const encrypted = await crypto.subtle.encrypt(
    {
      name: "RSA-OAEP",
      hash: "SHA-256"
    },
    publicKey,
    new TextEncoder().encode(data)
  );
  return btoa(String.fromCharCode(...new Uint8Array(encrypted)));
}

Complete Payload Example

For a contact form with email and phone:

User Input:

  • Email: Kurka.Vojtech@gmail.com
  • Phone: +420 606 199 831

ME SDK Payload:

{
  "email_hash": "1AF6402BFF01BF4C9C59760A1AD70C0F9AC6581E1F1BC6F0E42CFD0E5507F849",
  "phone_hash": "1252E4992ABDDA7AFEC3BD5243C5DA5426A051AAA4B9CE879A2A0DA063C8AD58",
  "email_rsa": "kebusJ6sLtgiN0n0l1ZtBk/V+sJAMg4DgBQO6UVSeOZt...",
  "phone_rsa": "mOfcZlyzJ9av00kVJK10cqoTTV3VnPLXr8LBZLCs..."
}

Data Flow

In CDP

  • Hashed values: Used for identity resolution and advertising platform uploads
  • Encrypted values: Stored securely, passed through to destination systems

In Destination Systems

  • Private key decryption: Convert encrypted values back to raw PII
  • Activation: Use raw PII for personalization and communication

Security Benefits

  • CDP isolation: No raw PII stored in CDP
  • Advertising compliance: Proper hashing for Meta, Google uploads
  • Destination access: Secure decryption in authorized systems only
  • Key management: Private keys never leave destination systems

Implementation Steps

  1. Generate key pair: Create RSA public/private key pair
  2. Distribute public key: Share with all data collection points
  3. Implement hashing: Add consistent sanitization and SHA256 hashing
  4. Implement encryption: Add RSA encryption for sensitive fields
  5. Update ME SDK: Send both hashed and encrypted values
  6. Configure destinations: Set up private key decryption

Testing and Validation

Hash Consistency Check

Verify identical inputs produce identical hashes across all sources:

// Test with same input from different sources
const testEmail = "test@example.com";
const hash1 = await hashEmail(testEmail); // Source A
const hash2 = await hashEmail(testEmail); // Source B
console.assert(hash1 === hash2, "Hash mismatch detected");

Encryption/Decryption Test

Validate the encryption-decryption cycle:

// Encrypt with public key
const encrypted = await encryptWithRSA(originalData, publicKey);

// Decrypt with private key (in destination system)
const decrypted = decryptWithPrivateKey(encrypted, privateKey);
console.assert(originalData === decrypted, "Decryption failed");

References

Support

For implementation assistance or questions about hashing and encryption setup, contact the Meiro support team.