Encryption is your friend but how are you using it?
  • Do NOT invent your own encryption algorithm.
  • DO INVENT your own encryption library.
  • The ONLY encryption algorithms you should consider are: AES-256, SERPENT and Two-Fish. I recommend using “SERPENT” over “AES”, however your encryption library could easily incorporate them all.
  • DO USE a library such as LibTomCrypt which is maintained. LibTomCrypt is available for every mainstream language. Other libraries exist and are equally valid if they are actively maintained and are at least 10 years old.
  • You MUST enable CBC mode when utilizing your encryption algorithm. You must ensure you are using the maximum number of rounds that your algo supports. AES (14), SERPENT (32), and TWOFISH (16).
  • All secrets and IV’s must be randomly generated using a cryprographically secure psuedo-random generator such as Lib/secrets.py for Python. (all other languages have similar options)
 $enc_text = library_CBC_encrypt($plain_text, $secret, $iv);
sub encrypt ($plain_text, $secret, $iv) {
$r_bytes = random_bytes(16);
$enc_text= library_encrypt( $r_bytes . $plain_text, $secret, $iv);
return $enc_text;
sub decrypt ($enc_text, $secret, $iv) {
$plain_text = library_decrypt($enc_text, $secret, $iv);
$plain_text = sub_string ($plain_text, 16);
return $plain_text;
  • Even if you have a weak “secret” (a catastrophe but not unusual) and a bad actor was attempting to brute-force-decrypt the plain-text “hello” they can no longer do that. (as you never encrypt “hello”)
  • Every current and future rainbow attack is nullified.
  • Assuming a future weakness is discovered in the underlying algorithm then almost certainly it will shall rely on multiple non-peppered analysis which you are protected against.
  • Your encryption library produces unique results with identical inputs.
sub encrypt ($plain_text, $secret, $iv, $hmac_secret) {
$r_bytes = random_bytes(16);
$enc_text = encrypt($r_bytes . $plain_text, $secret, $iv);
$hmac = blake2b_mac (16, $enc_text, $hmac_secret);
return $hmac . $enc_text;
sub decrypt ($enc_text, $secret, $iv, $hmac_secret) {
$hmac = blake2b_mac (16, sub_string($enc_text,16), $hmac_secret);
return failure if $hmac not equal to sub_string($enc_text,0,16);
$plain_text = decrypt( sub_string ($enc_text, 16), $secret, $iv);
return $plain_text;
  • Forename, surname
  • Email address
  • Address, geographic
  • Credit cards
  • Telephone numbers
  • Driving license / social security / TAX ID’s / etc..
  • Date of birth
  • ID link. (for instance Telegram ID or WhatsAPP ID)
sub hash ($text_to_hash, $hash_pepper) {
$hash = blake2b_hash ( $text_to_hash . $hash_pepper );
return $hash;
SELECT decrypt(email_enc) WHERE email_hash = hash(email_address);

Here is a PERFECT way to store passwords:

sub store_password 
($txt_passwd, $secret, $iv, $hmac_secret, $hash_pepper, $salt) {
// $salt is 16 x random bytes (per USER_ID) & stored (somewhere) linked to USER_ID. $hash_pepper is static. $salt is per user unique. $passwd_hash = hash ($txt_passwd, $hash_pepper . $salt);
$argon_passwd = ARGON2 ($passwd_hash, $salt);
$store_passwd = encrypt($argon_passwd, $secret, $iv, $hmac_secret);
// So now we have a TEXT PASSWORD provided by the user which we initially HASH to our own unique formula and is reproducible.// Then we ARGON it up using a reproducible and stored SALT. More on ARGON later. You SHOULD be using ARGON or bCrypt is acceptable too.// Finally, we encrypt and HMAC authenticate which is not reproducible but can be reversed using the correct decrypt parameters. return $store_passwd;
sub check_password
($txt_passwd, $secret, $iv, $hmac_secret, $hash_pepper, $salt, $id){
// $id is the USER_ID for the password to be looked up.
$store_passwd = SELECT $store_passwd FROM $USER_ID;
// So let's decrypt our stored password from the database....
$argon_passwd = decrypt($store_passwd, $secret, $iv, $hmac_secret)
// Now we re-create the HASH using the supplied text password as b4
$passwd_hash = hash ($txt_passwd, $hash_pepper . $salt);
// Now let's verify the $argon_passwd with the supplied $txt_passwd
$verify = argon_verify ($argon_passwd, $passwd_hash);
return $verify;
  • We use our own HASH routine to take the plain_text password and we add our unique per USER_ID salt to the HASH which also contains our own static PEPPER thus creating our own plain_text password which we then use ARGON to define the key.
  • ARGON is a key derivation algorithm suitable to convert any password into a cryptographic key. It offers variable time and memory costs as well as output size which can be configured based on your requirements.
  • We encrypt the resulting output from ARGON and actually store the encrypted ARGON key in the database, REDIS or other.
  • We’ve created our own custom encryption and decryption libraries which yield significant security increases yet operate on proven underlying cryptographic libraries.
  • We authenticate and verify the integrity when decrypting.
  • We have our own custom HASH routines with PEPPER.
  • We can store any information in a super secure way and we can lookup this information just as before by adding an additional lookup column to our data which is our custom Blake2b HASH.
  • Passwords are secured using salts, peppers, ARGON derivation and finally encrypted into the main database.
  • And all in just a few lines of code.
  • And this forms just the beginning of how you can build and extend your own libraries to work from.





Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Mark Arnold

Mark Arnold

The simplest most advanced appointment system in the world.