Files
pynkode/docs/templates/encipher_decipher_renew_nkode_v2.template.md
2025-12-03 11:36:43 -06:00

4.8 KiB

Encipher, Decipher and Renew nKode

Tenant Policy

  • max nkode length: {{ max_nkode_len }}
  • number of keys: {{ numb_of_keys }}
  • properties per key: {{ props_per_key }}
  • total number of properties: {{ numb_of_keys * props_per_key }}

Deterministic CSPRNG

  • AES-CTR DRBG
  • ChaCha20

User Cipher Keys

Derive keys in memory from PRNG above:

  • property key: {{ user_property_key }}
  • passcode key: {{ pass_key }}
  • user position key: {{ user_position_key }}
  • mask key: {{ mask_key }}

User Keypad

  • keypad example:
    {{ login_keypad_md }}
  • user passcode indices: {{ user_passcode_idxs}}

nKode Cipher

Passcode Hash

block-beta
    columns 2
    prop["user_property_key\n{{user_property_key}}"]
    pass["user_passcode_indices\n{{user_passcode_idxs}}"]
    space:2
    sel(("select\nproperties")):2
    pass --> sel
    prop --> sel
    space:2
    passcode["user passcode properties:\n{{user_passcode_props}}"]:2
    sel --> passcode
    space:2
    pad["zero pad to\nmax nkode length: {{max_nkode_len}}"]:2
    passcode -->pad
    space:2
    paddedpasscode["padded passcode:\n{{padded_passcode}}"]
    pad --> paddedpasscode
    passkey["passcode key:\n{{pass_key}}"]
    space:2
    xor2(("XOR")):2
    passkey --> xor2
    paddedpasscode --> xor2
    space:2
    cipheredpass["ciphered passcode:\n{{ciphered_passcode}}"]:2
    xor2 --> cipheredpass
    space:2
    hash(("hash")):2
    cipheredpass --> hash
    space:2
    cipheredhashed["hashed ciphered passcode:\n{{code}}"]:2
    hash --> cipheredhashed

Mask Encipher

block-beta
    columns 2
    passcode_idx["passcode indices:\n{{user_passcode_idxs}}"]
    
    space:3
    propidx(["Get Position Idx:\nmap each to element mod props_per_key"])
    passcode_idx-->propidx
    space:3
    passcode_position_idx["passcode poition indices:\n{{passcode_position_idxs}}"]
    propidx --> passcode_position_idx
    
    space:3
    pad1(("Pad with\nrandom indices"))
    passcode_position_idx --> pad1
          
    space:3
    posidx["Padded Passcode Position Indices:\n{{pad_user_passcode_idxs}}"]
    pad1 --> posidx
    user_pos["user position key:\n{{user_position_key}}"]
    
    space:2
    sel(("select positions"))
    user_pos --> sel
    posidx --> sel
    space:3
    passcode_pos["ordered user passcode positions:\n{{ordered_user_position_key}}"]
    sel --> passcode_pos
    mask_key["mask key\n{{mask_key}}"]
    space:2
    xor2(("XOR"))
    mask_key --> xor2
    passcode_pos --> xor2
    space:3
    mask["enciphered mask:\n {{mask}}"]
    xor2 --> mask

Validate nKode

block-beta
    columns 3
    selected_keys["keys selected by user during login:\n{{selected_keys}}"]
    login_keypad["login keypad:\n{{login_keypad}}"]
    space:4
    
    selectkeys(("filter keys"))
    mask["enciphered mask:\n {{mask}}"]
    mask_key["mask key:\n{{mask_key}}"]
    space:2
    
    xor1(("XOR"))
    mask --> xor1
    mask_key --> xor1
    selected_keys --> selectkeys
    login_keypad --> selectkeys
    space:3 
    
    ordered_keys["ordered keys:\n{{ordered_keys}}"]
    user_position_key["user position key:\n{{user_position_key}}"]
    passcode_pos["ordered user passcode positions:\n{{ordered_user_position_key}}"]
    selectkeys --> ordered_keys
    xor1 --> passcode_pos
    space:8 
    
    get_passcode_idxs(("recover passcode\nposition indices"))
    user_position_key --> get_passcode_idxs
    passcode_pos --> get_passcode_idxs
    space:8
    
    passcode_pos_idxs["padded passcode position indices:\n{{pad_user_passcode_idxs}}"]
    get_passcode_idxs --> passcode_pos_idxs
    space:3
    
    get_presumed_idxs(("recover passcode\nproperty indices")) 
    ordered_keys --> get_presumed_idxs
    passcode_pos_idxs --> get_presumed_idxs
    space:5
    
    passcode_prop_idxs["presumed passcode property indices:\n{{user_passcode_idxs}}"]
    prop["user_property_key\n{{user_property_key}}"]
    cipheredhashed["hashed ciphered passcode:\n{{code}}"]
    get_presumed_idxs --> passcode_prop_idxs
    space:3
    
    sel(("select\nproperties"))
    passcode_prop_idxs --> sel
    prop --> sel
    space:5
    
    passcode_prop["presumed passcode properties:\n{{user_passcode_props}}"]
    sel --> passcode_prop
    space:5
    
    cipher(("encipher"))
    passcode_prop --> cipher
    space:5
    
    cipheredpass["ciphered passcode:\n{{ciphered_passcode}}"]
    cipher --> cipheredpass 
    space:7


    comp{"compare"}
    cipheredpass --> comp
    cipheredhashed --> comp
    space:5 
    
    suc(("success")) 
    comp --"Equal"--> suc

Renew

A renewal happens every login

Nonce Renew

With ChaCha20, we can renew the keys and hash every login with a new nonce

Secret Renew

The secret is renewed less frequently. It's stored securely using a service like AWS Secrets Manager.