Migrate Markdown-Notes: projects, meetings, reference, personal
This commit is contained in:
184
archive/nkode_tutorial.md
Normal file
184
archive/nkode_tutorial.md
Normal file
@@ -0,0 +1,184 @@
|
||||
# nKode Tutorial
|
||||
|
||||
## nKode Keypad
|
||||
|
||||
- nKode keypad contains keys
|
||||
- Each key has icons
|
||||
- Each icon belongs to a set and has an index value associated with it
|
||||
- The position within the key is the set value
|
||||
- When attributes are shuffled, they'll always remain in the same position within the key
|
||||
(note: the set value can be obuscated from the client but we find it helpful to quickly find the attribute)
|
||||
|
||||
## nKode Enrollment
|
||||
|
||||
- user sets then confirms their nKode
|
||||
- Set and Confirm are dipersion of each other and allow the server to infer the users nKode
|
||||
- the users login has additional icons added to each to key to make it dispersion resistant
|
||||
- After the user as selected their nKode through the set and confirms,
|
||||
the server can infer the users selection since each key selection will only have one icons in common.
|
||||
- The users nKode is enciphered, salted and hashed.
|
||||
|
||||
## Dispersion
|
||||
|
||||
- Two keypads are dispersion of each other if:
|
||||
Kp1: Keypad 1
|
||||
Kp2: Keypad 2
|
||||
|
||||
for each key1 in Kp1:
|
||||
for each key2 in Kp2:
|
||||
iconsIntersection(key1, key2) <= 1
|
||||
|
||||
|
||||
## Dispersion Algo
|
||||
|
||||
- Convert a Keypad view into a matrix view
|
||||
- each row is key and each column is a set
|
||||
- Fisher Yates the keys i.e. the rows in the matrix
|
||||
- Fisher Yates an identity matrix equivalent to the number of keys
|
||||
- The shuffled permutation is used to rotate the columns
|
||||
|
||||
|
||||
## Dispersion Resistance
|
||||
|
||||
- Dispersion is only possible if {number of icons per key} <= {number keys in the keypad}
|
||||
- If there are more icons per key than keys, it makes it difficult to phish for a users nkode
|
||||
|
||||
|
||||
## Cipher Keys
|
||||
|
||||
#### attribute key
|
||||
|
||||
- randomly generated array of unsigned integars
|
||||
- array of length {numb of keys} * {number of attributes per key}
|
||||
- xored with ss-attr to give each user a unique
|
||||
|
||||
#### passcode key
|
||||
|
||||
- randomly generated array of unsigned integars
|
||||
- array of length {max nKode length}
|
||||
- xored with final user passcode
|
||||
|
||||
#### set key
|
||||
|
||||
- used to recover users nkode set values
|
||||
- array of unsigned integars
|
||||
- each elemenet in the array is a random number XOR'ed with the set value of the users nKode
|
||||
- so `for set_key_i in user_set_key`
|
||||
`set_key_i = user_passcode_set_i ^ random_set_key_i`
|
||||
|
||||
#### mask key
|
||||
|
||||
- used to recover users nkode set values
|
||||
- array of random unsigned integars
|
||||
|
||||
#### server-side attributes (ss-attr) and sets (ss-set)
|
||||
|
||||
- Each icon has a server side attribute.
|
||||
- The icon and the ss-attr are indexed to the same place in an array.
|
||||
- The dispersion and shuffle operation are applied to the index array and the index array is applied to the icon and ss-attr
|
||||
- ss-attrs are randomly generated permutation of unsigned ints (or byte arrays of any length for extra security)
|
||||
|
||||
### Encipher and Hash nKode Passcode
|
||||
passcode = index values of the selected icons infered in set/comfirm
|
||||
user_attrs = arr_xor(ss_attr, user_attr_key)
|
||||
passcode_attr = [user_attrs[idx] for idx in passcode]
|
||||
|
||||
ciphered_passcode = arr_xor(passcode_attr, user_passcode_key)
|
||||
|
||||
// optional sha256 if ciphered_passcode is more than 72 bytes
|
||||
passcode_digest = sha256(ciphered_passcode)
|
||||
|
||||
hashed_passcode = bcrypt(passcode_digest)
|
||||
|
||||
### Enicphering nKode Set
|
||||
|
||||
nKode mask is used to recover the users nKode
|
||||
1. set_key_i = (set_rand_numb_i ^ set_val_i)
|
||||
2. mask_key_i = mask_rand_numb_i
|
||||
|
||||
passcode = index values of the selected icons infered in set/comfirm
|
||||
// recall ss_set array is an order list
|
||||
set_idx = get_set_value(passcode)
|
||||
user_set_keys = [set_key[idx] for idx in set_idx]
|
||||
user_set_vals = [ss_sets[idx] for idx in set_idx]
|
||||
mask = arr_xor(user_set_val, user_set_keys, mask_key)
|
||||
|
||||
- mask_i = mask_key_i ^ padded_passcode_server_set_i ^ set_key_i
|
||||
- mask_i = mask_rand_num_i ^ set_val_i ^ set_rand_numb_i ^ set_val_i
|
||||
- mask_i = mask_rand_num_i ^ set_rand_numb_i # set_val_i is cancelled out
|
||||
|
||||
#### nKode Validation
|
||||
// set_val_i = mask_i ^ set_key_i ^ mask_key_i
|
||||
// selected_keys the keys the user selects
|
||||
recovered_set_vals = arr_xor(mask, set_key, mask_key)
|
||||
user_keypad = get_user_keypad(username)
|
||||
|
||||
presumed_password = get_pressumed_passcode(user_key, selected_keys, recovered_set_val)
|
||||
|
||||
if is_valid_passcode(presumed_password, hashed_passcode)
|
||||
return LOGIN_SUCCESS
|
||||
else
|
||||
return LOGIN_FAIL
|
||||
|
||||
|
||||
## nKode Login Shuffle
|
||||
|
||||
- After a successful login, the users keypad is shuffled in a two step process:
|
||||
1. the keys are randomly shuffled
|
||||
2. half the sets are randomly shuffled
|
||||
- We've found this works best for xyz reason and we're also working on simulations to find a probablity curve for number of overserveration before an adversery can crack an nkode
|
||||
|
||||
|
||||
## nKode Login
|
||||
|
||||
- When a user request their nkode keypad, the server sends a list of svgs in the order they should be displayed
|
||||
- The Gen2 demo implementation works a bit different it sends the svgs indexed in order from 0-total_numb_of_attr along with an index array for how the svgs should be ordered
|
||||
- this is a legacy from the gen 1 keypad but it helps to make the implemntation more concrete so we'll use this legacy
|
||||
- The frontend organized the svgs into keys and displays them.
|
||||
- The user selects keys for their nkode and their key selection is sent back to the server for validation
|
||||
|
||||
|
||||
## Preventing User Enumeration
|
||||
|
||||
- This isn't applied in the demo application
|
||||
- We can prevent a threat actor from enumerating users.
|
||||
- if a valid email is entered into the login for a user that dne, we can create a ghost keypad and have it behave as if it were a real user.
|
||||
- if there are too many "failed nkode attempts" we lock the non-existing user out.
|
||||
- We can prevent timing attacks by either mocking the real control flow or setting a 1 or 2 sec response delay from the time the login request was recieved thereby completely elimiating timing attacks
|
||||
|
||||
## Renew
|
||||
Renew changes user ciphers, user salt, ss_attr, and ss_set.
|
||||
This is import in the event of a partial database hack or leak.
|
||||
An admin or cron job can run the renew with any frequency (daily, weekly, monthly)
|
||||
Users are aware of this process.
|
||||
Nothing changes for them.
|
||||
|
||||
### Three Step Renew
|
||||
Renew has three phases
|
||||
|
||||
1. Server-Side Attribute Renewal: ss_attr and ss_set values are replaced with new values
|
||||
2. Intermdiate User Renewal: every user goes through an intermediate phase before full Renewal
|
||||
3. Full User Renewal: The user's first successful login completes the renewal. User has gets new salt, and cipher
|
||||
|
||||
#### Server-Side Attribute Renewal
|
||||
|
||||
old_ss_attr, old_ss_set = get_ss_vals()
|
||||
renew_ss_vals() // new randomly generated values
|
||||
new_ss_attr, new_ss_set = get_ss_vals()
|
||||
|
||||
xor_ss_attr = arr_xor(old_ss_attr, new_ss_attr)
|
||||
xor_ss_set = arr_xor(old_ss_set, new_ss_set)
|
||||
|
||||
#### Intermdiate User Renewal
|
||||
|
||||
all_users = get_all_users()
|
||||
for user in all_users:
|
||||
user.renew = True // This flags the server to complete phase 3, full user renewal
|
||||
user.set_key = xor_lists(user.set_key, xor_ss_set) // recall user.set_key = rand_num ^ old_ss_set. this operation cancels out old_ss_set and replaces it with new_ss_set
|
||||
user.attribute_key = xor_lists(user.attribute_key, xor_ss_attr) // recall user.attribute_key ^ old_ss_attr are the user's nkode ss attributes so when we
|
||||
|
||||
#### Full User Renewal
|
||||
|
||||
After a successful login user keys are reset as if the user was signing up for the first time
|
||||
|
||||
|
||||
Reference in New Issue
Block a user