An experimental ID obfuscator based on symmetric cryptography.
From 133742
to hgb95qpcy4y50
- Your internal
uint64
-typed ID (e.g., autogenerated by your RDBMS):133742
- The "public" (encrypted) ID derived from it:
5781761883846612620
(still anuint64
) - The human version (and URL-safe) of the public ID:
hgb95qpcy4y50
(Crockford's Base 32-encoded.)
Use of Blowfish (from golang.org/x/crypto
) because:
- it works on 64-bit blocks (the secret key can be much larger though),
- it provides format-preserving encryption
(the encrypted ID is an
uint64
integer as well.)
This method does not make use of authenticated encryption (AE/AEAD). It only
does a permutation (one-to-one mapping between uint64
and itself) in a secret
manner (assuming the secret key is strong enough).
The direct consequence is that any uint64
integer is a valid ciphertext.
That lets an attacker "forge" valid obfuscated IDs (valid ciphertexts) to try
to gain access to unauthorized resources, thus dismissing some use cases.
Examples of invalid use cases:
- as a token for a password reset flow
- as a token that is part of a secret shareable URL
The typical valid use case: prevent from disclosing internal information,
e.g., by showing /order/hgb95qpcy4y50
instead of /order/133742
(which may disclose the number of orders), assuming the resource is accessed by
authorized (e.g., logged) users anyway.
Code:
hider, _ := idhider.NewIDHider([]byte("xxxxxxxxxxxxxxxx")) // 128-bit secret key
var id uint64 = 42
fmt.Println("Internal ID (secret):", id)
hid := hider.HumanPublicID(id)
fmt.Println("Human public ID:", hid)
fmt.Println("Back to internal secret ID:", hider.HumanToID(hid))
Output:
Internal ID (secret): 42
Human public ID: m1n033ptmfrxp
Back to internal secret ID: 42