How to protect numerical Id ? (obfuscate, id encryption)


This page is about how to obfuscate / protect a internal id. So that even if they are public, they cannot be guessed.


This is mostly used to prevent guessing your data.

Estimate business data

For instance, you can estimate the number of orders

Prevent DDOS attack - Prevent id forgery

You can prevent a ddos.

Because this is not shown as a sequence, the attacker cannot guess or create the ids.

  • Bad ids are catched before hitting the database.
  • Good ids are generally fetch once and put in cache (meaning that if there is repeated requests in a short period of time, the data will not hit the database but the cache).

Prevent information leaking

Because this is not shown as a sequence, you can prevent a scanning of public data and extraction of information. If you have a public page, the attacker cannot guess, the next id.

Encryption Method

The id are encrypted using a symmetric cipher with a secret and a salt because there is only one party, you.


Stronguest Description Note
strong key Advanced Encryption Standard (AES) generally with a hash-based message authentication code (HMAC) to protect the IDs from being altered by the attacker
less strong alphabet shuffle the most known example is the hashid library



  • Number to text with salt: - YouTube-like ids from numbers - Use it when you don't want to expose your database ids to the user.


let minimalHashLength = 8;
let hashAlphabet = "abcdefghijklmnopqrstuvwxyz1234567890";
let hashids = new Hashids("this is my salt", minimalHashLength, hashAlphabet)
let encode1 = hashids.encode([1]);
let decode1 = hashids.decode(encode1);
console.log(`The value 1 encoded is: ${encode1}`);
console.log(`The encoded value ${encode1} decoded is: ${decode1}`);
  • Hashid will return an empty array if it can't decode
let badvalue = "badvalue";
let decodedBadValue = hashids.decode(badvalue);
console.log(`The bad value (${badvalue}) decoded is an empty array: ${decodedBadValue}`);
  • You can encode multiple value
let multipleValues = [1,2];
let multipleValuesEncoded = hashids.encode(multipleValues);
console.log(`Mutliple values (${multipleValues}) are encoded to ${multipleValuesEncoded}`);
let multipleValuesDecoded = hashids.decode(multipleValuesEncoded);
console.log(`Mutliple values encoding (${multipleValuesEncoded}) are decoded to ${multipleValuesDecoded}`);
  • Because you can encrypt by part, you can also encode an Uuid
let uuidString = uuid.v4();
let uuidByteArray = uuid.parse(uuidString); // 16 bytes array
let dataViewByteArray = new DataView(uuidByteArray.buffer, 0);
let uuidTimeLow = dataViewByteArray.getUint32(0);
let uuidTimeMid = dataViewByteArray.getUint16(4);
let uuidTimeHighAndVersion = dataViewByteArray.getUint16(6);
let uuidClokSeq = dataViewByteArray.getUint16(8);
let uuidNode1 = dataViewByteArray.getUint32(10);
let uuidNode2 = dataViewByteArray.getUint16(14);
let uuidHashed = hashids.encode([uuidTimeLow,uuidTimeMid,uuidTimeHighAndVersion,uuidClokSeq,uuidNode1, uuidNode2]);
console.log(`The uuid ${uuidString} has been encoded to ${uuidHashed} of length ${uuidHashed.length}`);



  • obfuscates id number into integer id (no text)
  • is based on Knuth's integer hash method


Id Mask

Specific Algorithm

Siv (Synthetic IV)

SIV solves both:

  • the key-wrap problem (deterministic authenticated-encryption)
  • and the problem of conventional (two-pass, nonce-based) authenticated-encryption

It produces:

  • a ciphertext having the same length as the plaintext
  • and a synthetic initialization vector.

AES-SIV ciphertexts are the size of the input + 128-bits (SIV tag), because it uses AES-CTR encryption.

Siv paper in 2006 by Phil Rogaway “A Provable-Security Treatment of the Key-Wrap Problem” 2) described in RFC 5297

Powered by ComboStrap