Number: SLIP-0013
Title: Authentication using deterministic hierarchy
Type: Standard
Status: Final
Authors: Pavol Rusnak <stick@satoshilabs.com>
Created: 2015-03-12
This document describes a method that is used for authenticating to various services such as websites or remote shells using a determinstic hierarchy.
Using Deterministic Hierarchy for authenticating into systems is ideal, because the same concepts of easy backup that relate to backing up deterministic wallets can be applied to backing up user identities.
Let's introduce the service identity. It consists of two elements:
a) RFC 3986 URI proto://[user@]host[:port][/path]
Examples:
https://example.com
ftp://public@example.com/pub
ssh://root@example.com:2222
b) index (32-bit unsigned integer)
The index is used so one can generate more keys corresponding to the same URI.
-
First concatenate
index
with the URI (uri
). Use little endian forindex
. -
Compute the SHA256 hash of the result (
hash
). -
Truncate
hash
to 128 bits (hash128
) -
Split
hash128
into four 32-bit integersA
,B
,C
,D
. Use little endian for each. -
Set highest bits of numbers
A
,B
,C
,D
to 1 (e.g. logical OR with 0x80000000) to harden -
Derive the HD node
m/13'/A'/B'/C'/D'
according to BIP32.
-
index + uri
=0
+https://satoshi@bitcoin.org/login
-
sha256(index + uri)
=d0e2389d4c8394a9f3e32de01104bf6e8db2d9e2bb0905d60fffa5a18fd696db
-
hash128
=d0e2389d4c8394a9f3e32de01104bf6e
-
A
= 2637750992,B
= 2845082444,C
= 3761103859,D
= 1858012177 -
A'
= 2637750992,B'
= 2845082444,C'
= 3761103859,D'
= 4005495825 -
bip32 node path
=m/2147483661/2637750992/2845082444/3761103859/4005495825
See a Python example.
Service issues the challenge consisting of three parts:
a) service identity described above (e.g. https://example.com 0
)
b) hidden challenge
- random bytes sequence of maximum length 64
- this won't be shown to the user
c) visual challenge
- arbitrary string of text of maximum length 64
- this will be shown to the user and we recommend using timestamp in
YYYY-MM-DD HH:MM:SS
format or similar
Signer takes this data and computes the private key according to section HD Structure. Then it concatenates sha256 hashes of challenge hidden and challenge visual and signs the result using the standard Bitcoin message signing. Finally, the signature is returned together with the node public key and node address.
It's up to service operator to take this message and react in three possible ways:
- signature is invalid or not present -> show error to user
- signature is valid, address/public key seen for the first time -> create user account
- signature is valid, address/public key known -> login to user account