diff --git a/Site/algorithm.html b/Site/algorithm.html index 36659335..0e08b180 100644 --- a/Site/algorithm.html +++ b/Site/algorithm.html @@ -85,10 +85,10 @@
- +Master Password uses a stateless algorithm that relies solely on its implementation and the user's inputs. The user is expected to remember the following information:
key
seed
seed
password
+ A note on types: +
- The user chooses a single master password, preferably sufficiently long to harden against brute-force attacks. Master Password recommends absurd two or three-word sentences as they're easily remembered and generally sufficiently high in entropy. + The user chooses a single master password, preferably sufficiently long to harden against brute-force attacks. Master Password recommends absurd three or four-word sentences as they're easily remembered and generally sufficiently high in entropy.
- The application then creates a scrypt key derivative from the user's password. This process takes quite a bit of processing time and memory. This step exists to make brute-force attempts at guessing the master password from a given output password far more difficult, to practically infeasible, even for otherwise vulnerable password strings. + The application then creates a scrypt key derivative from the user's password. This process takes quite a bit of processing time and memory. This step exists to make brute-force attempts at guessing the master password from a given output password far more difficult, to practically infeasible, even for otherwise vulnerable password strings.
key = scrypt( P, S, N, r, p, dkLen )
where
- P = master password (UTF-8)
- S = <empty>
- N = 16384
+ P = master password
+ S = "com.lyndir.masterpassword" . name length . name
+ N = 32768
r = 8
- p = 1
+ p = 2
dkLen = 64
@@ -167,8 +174,7 @@
These input values are combined in a byte array, separated by a single NUL
byte. In order, the input values are the site name
(UTF-8 decoded), the master key
, and a salt
(this is the password counter, a 32-bit unsigned integer in network byte order). The byte array is hashed using the SHA-1 algorithm to yield the seed
as a result.
- salt = htonl( password counter )
- seed = sha1( site name . "\0" . key . "\0" . salt )
+ seed = hmac-sha256( key, "com.lyndir.masterpassword" . site name length . site name . counter )
Since the idea is that the output password can be used directly as a password to protect the user's account on the site, it needs to be able to pass the site's password policy.
- Master Password addresses this problem by introducing password types. Each password type describes what an output password must look like and maps to a set of ciphers
. Ciphers describe the resulting output password using a series of characters that map to character groups of candidate output characters. A cipher has the same length as the output password it yields. Each character in the cipher maps to a specific character group. At each position of the output password, a character is chosen from the character group identified by the character in the cipher at the same position.
+ Master Password addresses this problem by introducing password types. Each password type describes what an output password must look like and maps to a set of templates
. Templates describe the resulting output password using a series of characters that map to character groups of candidate output characters. A template has the same length as the output password it yields. Each character in the template maps to a specific character group. At each position of the output password, a character is chosen from the character group identified by the character in the template at the same position.
- The following ciphers are defined: + The following templates are defined:
CvcvCvcvnoCvcv
CvcvnoCvcvCvcv
CvcvCvcvCvcvno
anoxxxxxxxxxxxxxxxxx
axxxxxxxxxxxxxxxxxno
CvcvnoCvcvCvcv
CvcvCvcvnoCvcv
CvcvCvcvCvcvno
CvccnoCvcvCvcv
CvccCvcvnoCvcv
CvccCvcvCvcvno
CvcvnoCvccCvcv
CvcvCvccnoCvcv
CvcvCvccCvcvno
CvcvnoCvcvCvcc
CvcvCvcvnoCvcc
CvcvCvcvCvccno
CvccnoCvccCvcv
CvccCvccnoCvcv
CvccCvccCvcvno
CvcvnoCvccCvcc
CvcvCvccnoCvcc
CvcvCvccCvccno
CvccnoCvcvCvcc
CvccCvcvnoCvcc
CvccCvcvCvccno
CvcnoCvc
CvcCvcno
Cvcn
aaanaaan
aaannaaa
nnnn
- To create the create the output password, the bytes in the seed
are encoded according to the cipher. The first seed
byte is used to determine which of the type's ciphers to use for encoding an output password. We take the byte value of the first seed
byte modulo the amount of ciphers set for the chosen password type and use the result as a zero-based index in the cipher list for the password type.
+ To create the create the output password, the bytes in the seed
are encoded according to the template. The first seed
byte is used to determine which of the type's templates to use for encoding an output password. We take the byte value of the first seed
byte modulo the amount of templates set for the chosen password type and use the result as a zero-based index in the template list for the password type.
- ciphers = [ "CvcvCvcvnoCvcv", "CvcvnoCvcvCvcv", "CvcvCvcvCvcvno" ]
- cipher = ciphers[ seed[0] % count( ciphers ) ]
+ templates = [ "CvcvCvcvnoCvcv", "CvcvnoCvcvCvcv", "CvcvCvcvCvcvno", ... ]
+ template = templates[ seed[0] % count( templates ) ]
- Now that we know what cipher to use for building our output password, all that's left is to iterate the cipher, and produce a character of password output for each step. When we iterate the cipher (index i
), we look in the character group identified by the character (string passChars
) in the cipher at index i
.
+ Now that we know what template to use for building our output password, all that's left is to iterate the template, and produce a character of password output for each step. When we iterate the template (index i
), we look in the character group identified by the character (string passChars
) in the template at index i
.
The following character groups (passChars
) are defined:
V
V
AEIOU
C
C
BCDFGHJKLMNPQRSTVWXYZ
v
v
aeiou
c
c
bcdfghjklmnpqrstvwxyz
A
(= V . C
)A
(= V . C
)AEIOUBCDFGHJKLMNPQRSTVWXYZ
a
(= V . v . C . c
)a
(= V . v . C . c
)AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz
n
n
0123456789
o
o
!@#$%^&*()
@&%?,=[]_:-+*$#!'^~;()/.
X
(= a . n . o
)X
(= a . n . o
)AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()
AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789@&%?,=[]_:-+*$#!'^~;()/.