idnits 2.17.1 draft-ladar-stacie-03.txt: Checking boilerplate required by RFC 5378 and the IETF Trust (see https://trustee.ietf.org/license-info): ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/1id-guidelines.txt: ---------------------------------------------------------------------------- No issues found here. Checking nits according to https://www.ietf.org/id-info/checklist : ---------------------------------------------------------------------------- No issues found here. Miscellaneous warnings: ---------------------------------------------------------------------------- == The copyright year in the IETF Trust and authors Copyright Line does not match the current year -- The document date (May 17, 2018) is 2165 days in the past. Is this intentional? -- Found something which looks like a code comment -- if you have code sections in the document, please surround them with '' and '' lines. Checking references for intended status: Experimental ---------------------------------------------------------------------------- -- Looks like a reference, but probably isn't: '0' on line 912 ** Obsolete normative reference: RFC 6125 (ref. 'TLS-PKIX') (Obsoleted by RFC 9525) Summary: 1 error (**), 0 flaws (~~), 1 warning (==), 3 comments (--). Run idnits with the --verbose option for more detailed information about the items above. -------------------------------------------------------------------------------- 2 Network Working Group L. Levison 3 Internet-Draft Lavabit LLC 4 Intended status: Experimental May 17, 2018 5 Expires: November 18, 2018 7 Safely Turn Authentication Credentials Into Entropy (STACIE) 8 draft-ladar-stacie-03 10 Abstract 12 This document specifies a method for Safely Turning Authentication 13 Credentials Into Entropy (STACIE) using an efficient Zero Knowledge 14 Password Proof (ZKPP), and is provided as a standalone component 15 suitable for use as a building block in other protocol development 16 efforts. The scheme was created to fill the emerging need for a 17 standard which allows a single low entropy password to be used for 18 user authentication and the derivation of strong encryption keys. 19 The design is modular, and is conservative in its use of an arbitrary 20 one-way cryptographic hash function. The security of the scheme 21 depends on the difficulty associated with reversing the hash function 22 output back into the plain text input. STACIE attempts to make 23 discovering the plain text input through the use of brute force more 24 difficult by correlating the amount of processing to the length of a 25 user's plain text password. The shorter the plain text password, the 26 more processing is required, with the amount of additional, 27 artificially required, work scaling exponentially for each character. 29 Status of This Memo 31 This Internet-Draft is submitted in full conformance with the 32 provisions of BCP 78 and BCP 79. 34 Internet-Drafts are working documents of the Internet Engineering 35 Task Force (IETF). Note that other groups may also distribute 36 working documents as Internet-Drafts. The list of current Internet- 37 Drafts is at http://datatracker.ietf.org/drafts/current/. 39 Internet-Drafts are draft documents valid for a maximum of six months 40 and may be updated, replaced, or obsoleted by other documents at any 41 time. It is inappropriate to use Internet-Drafts as reference 42 material or to cite them other than as "work in progress." 44 This Internet-Draft will expire on November 18, 2018. 46 Copyright Notice 48 Copyright (c) 2018 IETF Trust and the persons identified as the 49 document authors. All rights reserved. 51 This document is subject to BCP 78 and the IETF Trust's Legal 52 Provisions Relating to IETF Documents 53 (http://trustee.ietf.org/license-info) in effect on the date of 54 publication of this document. Please review these documents 55 carefully, as they describe your rights and restrictions with respect 56 to this document. Code Components extracted from this document must 57 include Simplified BSD License text as described in Section 4.e of 58 the Trust Legal Provisions and are provided without warranty as 59 described in the Simplified BSD License. 61 Table of Contents 63 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 64 2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 4 65 3. Encodings . . . . . . . . . . . . . . . . . . . . . . . . . . 4 66 4. Derivation Process . . . . . . . . . . . . . . . . . . . . . 4 67 4.1. Hash Rounds . . . . . . . . . . . . . . . . . . . . . . . 7 68 4.2. Entropy Extraction . . . . . . . . . . . . . . . . . . . 9 69 4.3. Key Derivation . . . . . . . . . . . . . . . . . . . . . 12 70 4.4. Token Derivation . . . . . . . . . . . . . . . . . . . . 13 71 4.5. Realm Key Derivation . . . . . . . . . . . . . . . . . . 14 72 5. Encryption . . . . . . . . . . . . . . . . . . . . . . . . . 17 73 5.1. Envelope . . . . . . . . . . . . . . . . . . . . . . . . 17 74 5.2. Payload . . . . . . . . . . . . . . . . . . . . . . . . . 18 75 6. Password Changes . . . . . . . . . . . . . . . . . . . . . . 21 76 6.1. Shallow Password Change . . . . . . . . . . . . . . . . . 21 77 6.2. Deep Password Change . . . . . . . . . . . . . . . . . . 22 78 6.3. Hybrid Password Change . . . . . . . . . . . . . . . . . 22 79 7. Protocol . . . . . . . . . . . . . . . . . . . . . . . . . . 22 80 7.1. Create User . . . . . . . . . . . . . . . . . . . . . . . 22 81 7.2. Login . . . . . . . . . . . . . . . . . . . . . . . . . . 23 82 7.2.1. Login Request . . . . . . . . . . . . . . . . . . . . 23 83 7.2.2. Login Response . . . . . . . . . . . . . . . . . . . 24 84 7.3. Password Authentication . . . . . . . . . . . . . . . . . 26 85 7.3.1. Authenticate Request . . . . . . . . . . . . . . . . 26 86 7.3.2. Authenticate Response . . . . . . . . . . . . . . . . 27 87 7.4. Password Change . . . . . . . . . . . . . . . . . . . . . 28 88 7.5. Fetch Realm Shards . . . . . . . . . . . . . . . . . . . 28 89 7.6. Add a Realm Shard . . . . . . . . . . . . . . . . . . . . 28 90 8. Security Considerations . . . . . . . . . . . . . . . . . . . 28 91 8.1. Servers . . . . . . . . . . . . . . . . . . . . . . . . . 29 92 8.2. Clients . . . . . . . . . . . . . . . . . . . . . . . . . 29 93 8.3. Shared . . . . . . . . . . . . . . . . . . . . . . . . . 29 95 9. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 30 96 10. Feedback . . . . . . . . . . . . . . . . . . . . . . . . . . 30 97 11. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 30 98 12. Normative References . . . . . . . . . . . . . . . . . . . . 31 99 Appendix A. Test Vectors . . . . . . . . . . . . . . . . . . . . 33 100 A.1. Inputs . . . . . . . . . . . . . . . . . . . . . . . . . 33 101 A.2. Outputs . . . . . . . . . . . . . . . . . . . . . . . . . 34 102 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 34 104 1. Introduction 106 A number of emerging client/server protocols are currently being 107 developed which rely on endpoint encryption schemes for protection 108 against server compromises and pervasive surveillance efforts. All 109 of these protocols share a common need for the ability to 110 authenticate users based on their account password, without having to 111 share a plain text password with the server. While several proposals 112 have emerged which rely on a Zero Knowledge Password Proof (ZKPP), 113 none of them provide a standardized method for deriving a symmetric 114 encryption key suitable for use with Authenticated Encryption with 115 Associated Data (AEAD) ciphers using the same user password. 117 This specification describes a standalone scheme which solves these 118 problems by Safely Turning Authentication Credentials Into Entropy 119 (STACIE). Unlike previous efforts, STACIE can uniquely provide a 120 configurable level of resistance against off-line brute force attacks 121 aimed at recovering the original plain text password, or the derived 122 encryption keys. Client side key stretching ensures attackers 123 capable of eavesdropping on connections protected by Transport Layer 124 Security (TLS), or with access to the authentication database on the 125 server, will be unable to derive a user's password or their symmetric 126 encryption keys. 128 STACIE is intended for use as a standalone component in other client/ 129 server protocol and application development efforts. While the 130 protocol examples provided below are simplified, the abstract 131 mechanism should easily translate into other encapsulation and 132 encoding formats. Likewise, STACIE has been designed in a modular 133 fashion, making it capable of using any arbitrary, but suitably 134 strong, one-way cryptographic hash function. To ensure 135 interoperability among different implementations, the Secure Hash 136 Algorithm (SHA2-512) [SHS] MUST be implemented, while support for the 137 newer Secure Hash Algorithm (SHA3-512) [PBH] and the Skein hash 138 function (Skein-512) [SKEIN], are OPTIONAL. 140 For improved security, STACIE has been designed to provide extension 141 points making it possible for specifications to extend the scheme 142 with support for alternate authentication factors. The goal of this 143 specification is to accommodate a large variety of security 144 requirements, while remaining conservative in its assumptions and its 145 use of any particular cryptographic primitives. 147 To accommodate the unpredictable pace of improvements in computer 148 hardware and processing power, STACIE includes a mechanism which 149 allows system operators to increase the difficulty level and 150 processing required by clients for key derivation beyond what is 151 mandated by this specification. 153 The purpose of this document is to discourage the proliferation of 154 multiple schemes for use by the variety of protocols currently in 155 development which need to safely derive a symmetric encryption key, 156 and authenticate a user with the server using a single low entropy 157 password. While STACIE introduces strategies designed to strengthen 158 key material against a variety of recently revealed threats, and 159 provides a measure of protection associated with deficiencies in the 160 randomness of human input, it is not intended as a call to change or 161 update existing protocols and specifications. 163 2. Terminology 165 The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", 166 "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and 167 "OPTIONAL" in this document are to be interpreted as described in RFC 168 2119 [KEYWORDS] when, and only when, they appear in all capitals, as 169 described by RFC 8174 [CAPITALIZATION]. 171 3. Encodings 173 This document represents all of the request and responses using 174 standard JavaScript Object Notation [JSON]. When an object value is 175 text, the native UTF-8 representation is supplied. Otherwise the 176 value is armored using the base64 encoding scheme defined in RFC 4648 177 [BASE], with the URL and filename safe character set defined in 178 Section 5, and assigned the identifier "base64url." In addition to 179 the standard base64url conversion, all trailing pad characters, line 180 breaks, white space, and other non-printable control characters MUST 181 be removed, as permitted by Section 3.2. [BASE] For the examples in 182 this document, line breaks only appear when the sample value exceeds 183 the available space. 185 4. Derivation Process 187 STACIE employs a multistage process which includes an extraction 188 stage, two key derivation stages, and two token derivation stages. 189 The stages MUST progress in a linear order because the output for 190 each stage is used as an input for the subsequent stage. The 191 extraction and key derivation stages require a user's plain text 192 password, while the token derivation stages do not. This allows the 193 derived tokens to be used for authentication, because they can be 194 generated and verified by a server without access to the plain text 195 password. 197 Implementations MUST never store a user's plain text password. 198 Client implementations which need the ability to authenticate and 199 access encrypted user data without user input MUST store the 200 verification token, and the individual realm hash. These values 201 provide the ability to authenticate with a server, and access the 202 realm specific encryption keys without additional user input. By 203 storing just these values, an implementation ensures a user's plain 204 text password is still REQUIRED to alter account credentials. This 205 allows a user to recover from an endpoint compromise by updating 206 their password, allowing for a point in time recovery. 208 Client implementations with support for automatic login capabilities 209 on platforms which provide a secure storage facility SHOULD make use 210 of this capability to protect the verification token, and realm 211 hashes. 213 *Required Inputs* 215 The derivation process requires the following inputs: 217 username 218 The normalized username. 220 password 221 The plain text user password. 223 *Optional Inputs* 225 salt 226 An additional non-secret, per-site, or per-user source of random 227 entropy. The salt value ensures output independence and provides 228 protection against computational reuse and precomputed table 229 lookups. Salt values MUST provide a minimum of 64 octets, and 230 SHOULD be less than 1,024 octets, with 128 octets the RECOMMENDED 231 length. Salt values SHOULD be aligned along a 32 octet boundary. 233 nonce 234 An array of randomly generated octets created by a server for each 235 login attempt, which MUST be combined with the verification token 236 to derive the ephemeral login token. The nonce value MUST be a 237 minimum of 64 octets, and SHOULD be less than 1,024 octets, with 238 128 octets the RECOMMENDED length. Nonce values SHOULD be aligned 239 along a 32 octet boundary. 241 bonus 242 The fixed number of additional iterations added to the iteration 243 count calculated dynamically based the password's length. 245 *Outputs* 247 rounds 248 The REQUIRED number of hash rounds used for the extraction and key 249 derivation stages. 251 master_key 252 The key value REQUIRED for deriving realm keys, and used to derive 253 the password key. 255 password_key 256 The second key derivation output, and REQUIRED for deriving the 257 verification token. The password is also used to authenticate 258 password updates. 260 verification_token 261 The persistent token stored on a server during account creation, 262 or following a password update and then used to authenticate 263 ephemeral login tokens in the future. 265 ephemeral_login_token 266 The ephemeral token value which proves knowledge of the 267 verification token for a singular login attempt, and is REQUIRED 268 to authenticate a session or connection. 270 *Example* 272 The following code, written in Python, demonstrates how to derive the 273 various outputs by calling the example functions provided in 274 subsequent sections: 276 # Derive the Rounds 277 rounds = RoundsDerivation(password, bonus) 279 # Extract the Seed 280 seed = SeedDerivation(rounds, username, password, salt) 282 # Keys 283 master_key = KeyDerivation(seed, rounds, username, password, \ 284 salt) 285 password_key = KeyDerivation(master_key, rounds, username, \ 286 password, salt) 288 # Tokens 289 verification_token = TokenDerivation(password_key, username, \ 290 salt) 291 ephemeral_login_token = TokenDerivation(verification_token, \ 292 username, salt, nonce) 294 # Derive the Realm Key 295 realm_key = RealmKeyDerivation(master_key, label, shard, salt) 297 # Extract the Cipher and Vector Keys 298 vector_key = RealmVectorKeyExtraction(realm_key) 299 tag_key = RealmTagKeyExtraction(realm_key) 300 cipher_key = RealmCipherKeyExtraction(realm_key) 302 # Encryption and Decryption 303 encrypted_data = RealmEncrypt(vector_key, tag_key, cipher_key, \ 304 secret_message) 305 decrypted_data = RealmDecrypt(vector_key, tag_key, cipher_key, \ 306 encrypted_data) 308 4.1. Hash Rounds 310 To improve the security of short passwords, STACIE requires client 311 implementations to calculate the appropriate number of iterations, or 312 "rounds" used for string concatenation during the seed stage and the 313 number hash rounds REQUIRED during the key derivation stages. The 314 rounds variable is based on the number of characters, with short 315 passwords requiring more rounds than long passwords. The variable 316 number of rounds was designed to make systematically checking all of 317 the possible plain text inputs more expensive in the event any of the 318 derived tokens are compromised. It does not inherently provide 319 security for predictable passwords which might be easily guessed. 321 To ensure the formula used to calculate the number of rounds, and the 322 required processing remains effective against brute force attacks in 323 the future, a fixed number of "bonus" rounds MAY be added beyond what 324 is required. The number of bonus rounds is dictated by the server 325 configuration and MUST be added to the number calculated based on 326 length. The bonus variable is primarily intended to offset 327 improvements in computer performance in the future, for 328 implementations which rely on hash algorithm after they've been 329 deprecated. 331 When calculating the number of dynamic hash rounds clients MUST first 332 determine the number of Unicode "characters" in a password, which is 333 distinct from the number of octets. Many character encodings, such 334 as UTF-8 use a variable number of octets per character, and the 335 number of octets MAY change based on the input method editor. For 336 consistency, the password MUST be converted into the UTF-8 encoding, 337 and the number of Unicode characters determined. Because UTF-8 is 338 capable of representing the same hashed characters using multiple 339 octets, and using different binary values based on the normalization 340 form, it is critical that the length used for this calculation is 341 always based on the number of Unicode characters. This will ensure 342 the number of rounds remains deterministic. 344 To determine the number of rounds, a client MUST subtract the number 345 of Unicode characters from the constant value 24. If the result is 346 negative, the value 1 MUST be used. The result of this calculation 347 is used as a "dynamic" exponent, which is raised using the base 2, 348 and the result is the "variable" number of rounds. The "bonus" 349 rounds MUST be added to the "variable" number to derive the total 350 number of rounds. 352 If the combined value of the dynamic and bonus values is less than 8, 353 the value 8 MUST be used. Alternatively, if the value exceeds 354 16,777,216 the value MUST be reduced to this maximum value. The 355 maximum value corresponds to the limit imposed by the use of the 3 356 octet counter employed during the entropy extraction and key 357 derivation stages. 359 Token derivation employs a fixed, 8 rounds, to avoid leaking 360 information about the password length. 362 *Example* 364 The following Python code demonstrates the proper method for deriving 365 the number of rounds: 367 def RoundsDerivation(password, bonus): 368 # Accepts a user password and bonus value, and calculates 369 # the number of iterative rounds required. This function will 370 # always return a value between 8 and 16,777,216. 372 # Identify the number of Unicode characters. 373 characters = len(password.decode("utf-8")) 375 # Calculate the difficulty exponent by subtracting 1 376 # for each Unicode character in a password. 377 dynamic = operator.sub(24, characters) 379 # Use a minimum exponent value of 1 for passwords 380 # equal to, or greater than, 24 characters. 381 dynamic = max(1, dynamic) 383 # Derive the variable number of rounds based on the length. 384 # Raise 2 using the dynamic exponent determined above. 385 variable = pow(2, dynamic) 387 # If applicable, add the fixed number of bonus rounds. 388 total = operator.add(variable, bonus) 390 # If the value of rounds is smaller than 8, reset 391 # the value to 8. 392 total = max(8, total) 394 # If the value of rounds is larger than 16,777,216, reset 395 # the value to 16,777,216. 396 total = min(pow(2, 24), total) 398 return total 400 4.2. Entropy Extraction 402 STACIE starts by deriving a fixed-length pseudorandom seed value 403 which is "extracted" by "concentrating" the low-entropy user password 404 into a short, but cryptographically strong pseudorandom value. 405 Future extensions which incorporate a second authentication source 406 that results in a quality pseudorandom value for the seed value may 407 find this stage unnecessary. 409 Unlike the key and token derivation stages, the entropy extraction 410 stage uses the Hashed Message Authentication Code [HMAC] algorithm, 411 which is also defined by National Institute of Standards and 412 Technology (NIST) as a Federal Information Processing Standard (FIPS) 414 [HMAC-FIPS]. Test vectors based on SHA2-512 are available 415 [HMAC-SHA]. 417 Implementations supporting the OPTIONAL SHA3-512 or Skein-512 hash 418 functions MUST use an HMAC implementation bsaed on the appropriate 419 SHA3-512 or Skein-512. Implementations SHOULD NOT use the Skein-MAC 420 alternative described by the Skein paper [SKEIN]. Future STACIE 421 extensions MAY provide alternative methods for seed extraction. 423 Unlike a simple hash, HMAC requires a 128 octet key value. The key 424 value for the entropy extraction stage is derived from the salt 425 value. If no salt value is available the username MUST be hashed and 426 used as a substitute for the salt value. If the provided salt value 427 is precisely 128 octets, then it MUST be used as the HMAC key. 429 When the provided salt is not 128 octets, then a key MUST be derived 430 using an appropriate hash function, which provides a 128 octet value 431 by digesting the salt value concatenated together with a counter 432 variable. The process is performed twice, with the counter variable 433 set to the values 0 and 1, respectively. The counter is digested as 434 a 3 octet big endian integer value. The two hash digest output 435 values MUST be concatenated to form the 128 octet HMAC key value. 437 The HMAC primitive also requires a "message" which is created using 438 the plain text password, which MUST be provided to the HMAC primitive 439 repeatedly, with the precise number of repetitions dictated by the 440 "rounds" variable. The digest produced by the HMAC function becomes 441 the 64 octet seed value used for the master key derivation stage. 443 *Example* 445 The following Python code demonstrates the proper method for 446 extracting the entropy seed value: 448 def SeedDerivation(rounds, username, password, salt=None): 449 # Concentrates and then extracts the random entropy provided 450 # by the password into a seed value for the first hash stage. 452 # If if an explicit salt value is missing, use a hash of 453 # the username as if it were the salt. 454 if salt is None: 455 salt = SHA512.new(username).digest() 457 # Confirm the supplied salt meets the minimum length of 64 458 # octets required, is aligned to a 32 octet boundary and does not 459 # exceed 1,024 octets. Some implementations may not handle salt 460 # values longer than 1,024 octets properly. 461 elif len(salt) < 64: 462 raise ValueError("The salt, if supplied, must be at least " \ 463 "64 octets in length.") 464 elif operator.mod(len(salt), 32) != 0: 465 warnings.warn("The salt, if longer than 64 octets, should " \ 466 "be aligned to a 32 octet boundary.") 467 elif len(salt) > 1024: 468 warnings.warn("The salt should not exceed 1,024 octets.") 470 # For salt values which don't match the 128 octets required for 471 # an HMAC key value, the salt is hashed twice using a 3 octet 472 # counter value of 0 and 1, and the outputs are concatenated. 473 if len(salt) != 128: 474 key = \ 475 SHA512.new(salt + struct.pack('>I', 0)[1:4]).digest() + \ 476 SHA512.new(salt + struct.pack('>I', 1)[1:4]).digest() 477 # If the supplied salt is 128 octets use it directly as the 478 # key value. 479 else: 480 key = salt 482 # Initialize the HMAC instance using the key created above. 483 hmac = HMAC(key, None, SHA512) 485 # Repeat the plain text password successively based on 486 # the number of instances specified by the rounds variable. 487 for unused in range(0, rounds): 488 hmac.update(password) 490 # Create the 64 octet seed value. 491 seed = hmac.digest() 493 return seed 495 4.3. Key Derivation 497 There are two successive key derivation stages. The master key is 498 first, and requires the extracted seed value derived in the previous 499 stage, along with the calculated number of rounds, the username, 500 password, and if available, the salt value. The master key MUST be 501 kept private. It provides the secret material needed to derive the 502 realm specific subkeys used to encrypt data on the client. 504 The second key derivation stage provides the password key. It uses 505 an identical process as the master key stage, with the exception of 506 the seed value being replaced by the master key value derived in the 507 first stage. The password key MUST be kept private until it comes 508 time for a user to update their password. Password updates require 509 sharing the password key with a server, which can then confirm the 510 value translates into the current verification token, before updating 511 the values stored in the authentication database. This ensures a 512 that a compromised authentication database can't be used by an 513 attacker to alter user passwords. 515 Each key derivation stage repeats the hash process by the variable 516 number of iterations dictated by the rounds variable. Assuming the 517 hash function remains securely one-way, this strategy ensures key 518 derivation requires a linear computational process. The amount of 519 processing time is a product of the difficulty imposed by the rounds 520 variable and a client's computational performance. The linear nature 521 of the process means the time required for individual rounds MAY be 522 shortened but the rounds MUST NOT be processed in parallel. 524 Hash values are generated by concatenating the input seed (or master 525 key value) together with the with the username, salt, password and 526 counter value. Successive rounds repeat the process, using an 527 incremented counter value, and include the output of the previous 528 round prepended to the input. The counter value MUST be digested as 529 a 3 octet big endian integer value, and represents a 0 based value 530 corresponding to the current round. 532 *Example* 534 The following Python code demonstrates the proper method for key 535 derivation, with the seed value either the extracted seed, or the 536 master key, depending on the stage: 538 def KeyDerivation(seed, rounds, username, password, salt=""): 539 # Hash the input values together using the input values, and 540 # repeat the process, with the number of iterations dictated by 541 # the rounds variable. 543 count = 0 544 hashed = "" 546 while count < rounds: 547 hashed = SHA512.new(hashed + seed + username + salt + \ 548 password + struct.pack('>I', count)[1:4]).digest() 549 count = operator.add(count, 1) 551 # The last digest output is returned as the key value. 552 return hashed 554 4.4. Token Derivation 556 The token derivation process is distinct from the key derivation 557 process because it is repeatable without knowing a user's password. 558 The password key is combined with other inputs to derive the 559 verification token, and the verification token is then shared with 560 the server, which can use it to authenticate future login attempts. 561 To prevent replay attacks, the verification token is combined with a 562 nonce value, and using the same token derivation process, a unique 563 ephemeral login token is generated for each session or connection. 565 Like the key derivation stages defined above, the seed value in the 566 sample code below represents the output from the previous stage, 567 which is either the password key or the verification token. This 568 value is concatenated together with the salt value, if applicable, 569 and a nonce value (when deriving the ephemeral token). A counter 570 value is also appended, with the value representing a 3 octet big 571 endian integer value, and corresponding to a 0 based count of the 572 current round. The output for each round is prepended to the input 573 of successive rounds, with a fixed 8 rounds performed during each 574 token derivation stage. 576 __Example__hashed 578 The following Python code demonstrates the proper method for token 579 derivation, with the seed value either the password key, or the 580 verificiation token, depending on the stage: 582 def TokenDerivation(seed, username, salt="", nonce=""): 583 # Hash the input values together using the input values, and 584 # repeat the process eight times. 586 count = 0 587 rounds = 8 588 hashed = "" 590 # Confirm the nonce, if it was provided, meets the minimum 591 # length of 64 octets, does not exceed 1,024 octets, and is 592 # aligned along a 32 octet boundary. Implementations may not 593 # handle nonce values larger than 1,024 octets properly. 594 if len(nonce) > 0 and len(nonce) < 64: 595 raise ValueError("Nonce values must be at least " \ 596 "64 octets in length.") 597 elif operator.mod(len(nonce), 32) != 0: 598 warnings.warn("The nonce value, if longer than 64 octets, " \ 599 "should be aligned to a 32 octet boundary.") 600 elif len(nonce) > 1024: 601 warnings.warn("The nonce should not exceed 1,024 octets.") 603 while count < rounds: 604 hashed = SHA512.new(hashed + seed + username + salt + \ 605 nonce + struct.pack('>I', count)[1:4]).digest() 606 count = operator.add(count, 1) 608 return hashed 610 4.5. Realm Key Derivation 612 Realm specific keys are used to access and authenticate symmetrically 613 encrypted user data. The realm label specifies the category and/or 614 type of data protected by a given realm key. Protocols which 615 incorporate STACIE MAY use a single realm, or separate data into 616 different realms based on the data type. Every realm is protected by 617 a unique encryption key. The realms are isolated to allow separable 618 handling, and isolation, such that if one realm key is compromised, 619 it is possible for the remaining realms to remain secure, provided 620 the master key was not compromised, or the attacker is unable to gain 621 access to the shard values for other realms. 623 The shard value is a randomly generated string of 64 octets, provided 624 after successful authentication, which allows a client to derive a 625 realm key. Because the shard is stored on the server, an endpoint 626 compromise won't yield the necessary information to decrypt any 627 locally stored data, after the user updates their credentials. This 628 will mitigate the damage that would occur when a device with cached 629 data is lost or stolen. 631 The unique key for a realm is derived by concatenating, then hashing 632 the master key, realm label, and salt. The resulting digest is then 633 combined with a realm shard value using the bitwise exclusive "or" 634 operation. The result is a "realm key" which contains the 635 concatenated vector key, tag key, and cipher key values. The vector 636 key is comprised of the first 16 octets, the tag key is protected by 637 the subsequent 16 octets, and the cipher key is comprised of the 638 final 32 octets. 640 *Required Inputs* 642 The master key, as previously described, is combined with the 643 following required inputs: 645 label 646 The realm label, a predefined lowercase string describing the 647 category and/or type of data. 649 The salt is only required if a salt value was used to derive the 650 master key: 652 salt An additional non-secret, per-site, or per-user source of 653 random entropy. The salt value increases the unpredictability of 654 the output. Salt values MUST provide a minimum of 64 octets, and 655 SHOULD be less than 1,024 octets, with 128 octets the RECOMMENDED 656 length. Salt values SHOULD be aligned along a 32 octet boundary. 658 *Outputs* 660 realm_key 661 The realm specific key distilled from the provided inputs, and is 662 the combination of the vector, tag and cipher key values. 664 vector_key 665 The key used to unlock the initialization vectors for a given 666 realm. 668 tag_key 669 The key used to unlock the authentication tags for a given realm. 671 cipher_key 672 The key used by the symmetric cipher to decrypt user data 673 associated with a given realm. 675 *Example* 676 The following Python code demonstrates how to derive and then 677 separate the keys for a given realm: 679 def RealmKeyDerivation(master_key, label="", shard="", salt=""): 681 if len(label) < 1: 682 raise ValueError("The realm label is missing or invalid.") 683 elif len(shard) != 64: 684 raise ValueError("The shard length is not 64 octets.") 685 elif len(master_key) != 64: 686 raise ValueError("The master key length is not 64 octets.") 688 # The salt value is optional, but if supplied, must be a minimum 689 # of 64 octets in length, and no more than 1,024 octets in 690 # length. It should be aligned to a 32 octet boundary. Some 691 # implementations may not handle salt values longer than 1,024 692 # octets properly. 693 elif len(salt) != 0 and len(salt) < 64: 694 raise ValueError("The salt, if supplied, must be at least " \ 695 "64 octets in length.") 696 elif len(salt) != 0 and operator.mod(len(salt), 32) != 0: 697 warnings.warn("The salt, if longer than 64 octets, should " \ 698 "be aligned to a 32 octet boundary.") 699 elif len(salt) > 1024: 700 warnings.warn("The salt should not exceed 1,024 octets." 702 realm_hash = SHA512.new(master_key + label + salt).digest() 703 realm_key = str().join(chr(operator.xor(ord(a), ord(b))) \ 704 for a,b in zip(realm_hash, shard)) 706 return realm_key 708 def RealmVectorKeyExtraction(realm_key): 709 vector_key = realm_key[0:16] 711 return vector_key 713 def RealmTagKeyExtraction(realm_key): 714 tag_key = realm_key[16:32] 716 return tag_key 718 def RealmCipherKeyExtraction(realm_key): 719 cipher_key = realm_key[32:64] 721 return cipher_key 723 5. Encryption 725 STACIE requires client implementations to support the Advanced 726 Encryption Standard [AES] using 256 bit key values. To ensure data 727 integrity, and protect against manipulation by a malicious server, 728 AES MUST be employed using the Galois Counter Mode [GCM]. The binary 729 format specifies a 34 octet envelope, followed by a payload aligned 730 to a 16 octet boundary. The payload includes a 4 octet prefix, and a 731 variable amount of padding appended as a suffix for alignment 732 purposes. 734 5.1. Envelope 736 Symmetrically encrypted buffers are preceeded by an envelope, 737 consisting of the realm serial number, the initialization vector 738 shard, and the authentication tag shard. The serial number is a 2 739 octet big endian integer corresponding to the realm key used to 740 derive the key values associated with a given buffer. It is possible 741 for a realm to have buffers encrypted using different serial numbers. 742 The number MAY be increased when users update their password. The 743 serial number is followed by a 16 octet initialization vector shard, 744 which MUST be randomly generated whenever data is encrypted. The 745 vector shard is combined with the vector key using a bitwise 746 exclusive "or" operation to produce the initialization vector used 747 for a given cipher text. The final envelope value is a 16 octet tag 748 shard, which like the vector shard, MUST be combined with the tag key 749 using a bitwise exclusive "or" operation to produce the 750 authentication tag for a given cipher text. 752 *Envelope Parameters* 754 serial 755 The serial number is a 2 octet big endian integer which delineates 756 which shard value for a given realm MUST be used to derive the 757 realm key. 759 vector_shard 760 The randomly generated 16 octet value generated during encryption, 761 and then combined with the vector key to using a bitwise exclusive 762 "or" operation. The result is the initialization vector for a 763 given cipher text. 765 tag_shard 766 A 16 octet authentication tag is created during the encryption 767 process, and then combined with the tag key using a bitwise 768 exclusive "or" operation to create the tag shard. To produce the 769 authentication tag for a cipher text, the tag key MUST be combined 770 with the tag shard using to another bitwise exclusive "or" 771 operation when the buffer is decrypted. 773 5.2. Payload 775 The envelope data is immediately followed by the encrypted payload, 776 which consists of the encrypted plain text value, a 4 octet prefix, 777 and up to 255 octets of padding appended after the plain text. The 778 entire encrypted/decrypted payload, including the prefix and suffix, 779 MUST align to a 16 octet boundary. The prefix begins with a 3 octet 780 big endian integer which denotes the length of the plain text value, 781 and is is followed by a single octet pad value. The pad value 782 indicates how many additional octets have been appended to the plain 783 text value t0 align the payload to the 16 octet boundary. The amount 784 of padding MUST include the requisite 0 to 15 octets required to 785 align the payload, but MAY also include a random amount of OPTIONAL 786 padding in 16 octet increments. Specifically, the pad value MAY 787 include an additional 16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 788 178, 192, 208, 224, or 240 octets beyond those required for 789 alignment. The padding octets appended after the plain text value, 790 or suffix, MUST match the value of the padding octet in the prefix. 792 size 793 The length of the plain text value represented as a 3 octet, big 794 endian integer. 796 pad 797 The amount of padding appended to the plain text value generated 798 16 octet value generated during encryption, and then combined with 799 the vector key to using a bitwise exclusive "or" operation. The 800 result is the initialization vector for a given cipher text. 802 buffer 803 A plain text value worthy of protection. 805 padding 806 Up to 255 octets of padding, with the padding octets all set to 807 the pad value. 809 *Example* 811 The following Python code demonstrates how to encrypt a plain text 812 value: 814 def RealmEncrypt(vector_key, tag_key, cipher_key, buffer, serial=0): 816 count = 0 818 if serial < 0 or serial >= pow(2, 16): 819 raise ValueError("Serial numbers must be greater than 0 " \ 820 "and less than 65,536.") 821 elif len(cipher_key) != 32: 822 raise ValueError("The encryption key must be 32 octets " \ 823 "in length.") 824 elif len(vector_key) != 16: 825 raise ValueError("The vector key must be 16 octets in " \ 826 "length.") 827 elif len(buffer) == 0: 828 raise ValueError("The secret being encrypted must be at " \ 829 "least 1 octet in length.") 830 elif len(buffer) >= pow(2, 24): 831 raise ValueError("The secret being encrypted must be at " \ 832 "less than 16,777,216 in length.") 834 vector_shard = get_random_bytes(16) 836 iv = str().join(chr(operator.xor(ord(a), ord(b))) \ 837 for a,b in zip(vector_key, vector_shard)) 839 size = len(buffer) 840 pad = (16 - operator.mod(size + 4, 16)) 842 while count < pad: 843 buffer += struct.pack(">I", pad)[3:4] 844 count = operator.add(count, 1) 846 encryptor = Cipher(algorithms.AES(cipher_key), modes.GCM(iv), \ 847 backend=default_backend()).encryptor() 848 ciphertext = encryptor.update(struct.pack(">I", size)[1:4] \ 849 + struct.pack(">I", pad)[3:4] + buffer) \ 850 + encryptor.finalize() 852 tag_shard = str().join(chr(operator.xor(ord(a), ord(b))) \ 853 for a,b in zip(tag_key, encryptor.tag)) 855 return struct.pack(">H", serial) + vector_shard + tag_shard \ 856 + ciphertext 858 The following Python code demonstrates how to decrypt and validate 859 the cipher text created by the encryption function above: 861 def RealmDecrypt(vector_key, tag_key, cipher_key, buffer): 863 count = 0 865 # Sanity check the input values. 866 if len(cipher_key) != 32: 867 raise ValueError("The encryption key must be 32 octets in "\ 868 " length.") 869 elif len(tag_key) != 16: 870 raise ValueError("The tag key must be 16 octets in length.") 871 elif len(vector_key) != 16: 872 raise ValueError("The vector key must be 16 octets in " \ 873 "length.") 874 elif len(buffer) < 54: 875 raise ValueError("The minimum length of a correctly " \ 876 "formatted cipher text is 54 octets.") 877 elif operator.mod(len(buffer) - 34, 16) != 0: 878 raise ValueError("The cipher text was not aligned to " \ 879 "a 16 octet boundary or some of the data is missing.") 881 # Parse the envelope. 882 vector_shard = buffer[2:18] 883 tag_shard = buffer[18:34] 884 ciphertext = buffer[34:] 886 # Combine the shard and key values to get the iv and tag. 887 iv = str().join(chr(operator.xor(ord(a), ord(b))) \ 888 for a,b in zip(vector_key, vector_shard)) 890 tag = str().join(chr(operator.xor(ord(a), ord(b))) \ 891 for a,b in zip(tag_key, tag_shard)) 893 # Decrypt the payload. 894 decryptor = Cipher(algorithms.AES(cipher_key), \ 895 modes.GCM(iv, tag), backend=default_backend()).decryptor() 896 plaintext = decryptor.update(ciphertext) + decryptor.finalize() 898 # Parse the prefix. 899 size = struct.unpack(">I", '\x00' + plaintext[0:3])[0] 900 pad = struct.unpack(">I", '\x00' + '\x00' + '\x00' + \ 901 plaintext[3:4])[0] 903 # Validate the prefix values. 904 if operator.mod(size + pad + 4, 16) != 0 or \ 905 len(plaintext) != size + pad + 4: 906 raise ValueError("The encrypted buffer is invalid.") 908 # Confirm the suffix values. 910 for offset in xrange(size + 4, size + pad + 4, 1): 911 if struct.unpack(">I", '\x00' + '\x00' + '\x00' + \ 912 plaintext[offset: offset + 1])[0] != pad: 913 raise ValueError("The encrypted buffer contained " \ 914 an invalid padding value.") 916 # Return just the plain text value. 917 return plaintext[4:size + 4] 919 6. Password Changes 921 6.1. Shallow Password Change 923 *Required Inputs* 925 The derivation process requires the following inputs: 927 new_master_key 928 The master key created using the new password. 930 new_salt 931 The salt value associated with the new password. Note this value 932 SHOULD be different following a password change. 934 realm_key 935 The realm specific key distilled using the previous password, 936 salt, and current shard value. 938 label 939 The realm label, a predefined lowercase string describing the 940 category and/or type of data. 942 *Outputs* 944 realm_shard 945 A replacement shard value, which will result in the same realm key 946 being derived when combined with the new master key. 948 *Example* 950 The following code, written in Python, demonstrates how to derive a 951 new realm shard value during password changes: 953 def RealmShardRotation(new_master_key, new_salt, realm_key, label): 955 if len(new_master_key) != 64: 956 raise ValueError("The master key is not 64 octets.") 957 elif len(new_salt) < 1: 958 raise ValueError("The salt is missing or invalid.") 959 elif len(realm_key) != 64: 960 raise ValueError("The previous realm key is not 64 octets.") 961 elif len(label) < 1: 962 raise ValueError("The realm label is missing or invalid.") 964 realm_hash = SHA512.new(new_master_key + label + new_salt).digest() 965 realm_shard = str().join(chr(operator.xor(ord(a), ord(b))) \ 966 for a,b in zip(realm_hash, realm_shard)) 968 return realm_shard 970 6.2. Deep Password Change 972 6.3. Hybrid Password Change 974 7. Protocol 976 7.1. Create User 978 When the birds mate with the bees a new account is born. 980 { register: 981 { username: "user-alias@example.tld" } 982 } 984 { recruit: 985 { username: "user-alias@example.tld", 986 salt: "Wb4vfzSpBpDRKafDlhhba3KhjIh09_4-IAl22XOcaI2z9O0QNdvNxFiRBM 987 qsyr4yD90OmDxBckHJzijGF7d1PEsrGwlGEb9YCVpNvKiIgLeAPxz1OB7mn03wL 988 RCfzYA8Ab8kvkinoZjHVnr6Fd34RS6bYB-mBB5WX2iQ-TBKZlE", 989 bonus: "131072", 990 hash: "sha2" } 991 } 993 { error: "Registration is currently disabled." } 994 { error: "The requested username is unavailable." } 995 { error: "A dramatic increase in cosmic radiation means registration 996 is temporarily unavailable." } 998 { enroll: 999 { username: "user-alias@example.tld", 1000 salt: "Wb4vfzSpBpDRKafDlhhba3KhjIh09_4-IAl22XOcaI2z9O0QNdvNxFiRBM 1001 qsyr4yD90OmDxBckHJzijGF7d1PEsrGwlGEb9YCVpNvKiIgLeAPxz1OB7mn03wL 1002 RCfzYA8Ab8kvkinoZjHVnr6Fd34RS6bYB-mBB5WX2iQ-TBKZlE", 1003 verification-token: "egf9dS64Z5b5qmrW4JYT86iNxDwHM5PvLF7DkyufIUwX 1004 2bAZ8p7iDcHNLVbT53_zZUMWgxWIxAxmWw6d8nAv9Q" } 1005 } 1007 7.2. Login 1009 The login process begins by submitting a "login" request with the 1010 response providing an array of method objects each with the 1011 parameters REQUIRED to compute the secret values needed for key 1012 derivation and the tokens used for authentication. This includes the 1013 password object which provides the nonce value REQUIRED to generate 1014 the ephemeral login token used to validate the session or connection. 1016 7.2.1. Login Request 1018 A login request supplies a single username parameter, which is 1019 REQUIRED, and ensures equivalent inputs always provide a common, 1020 deterministic outcome. 1022 *Required Parameters* 1024 username 1025 The username value provide must be submitted to the server for 1026 normalization, canonicalization and alias mapping to ensure a 1027 deterministic result. The specific rules applied are determined 1028 by the account policies and system locale for the server. 1029 Typically, this will include lower-case characters, decomposing 1030 ambiguous characters, adding, removing or altering the domain name 1031 component, and mapping aliases to a real username. 1033 *Example* 1035 { login: 1036 { username: "user-alias@example.tld" } 1037 } 1039 7.2.2. Login Response 1041 The response provides an array of method objects corresponding to 1042 different authentication mechanisms along with any requisite 1043 parameters. A disposition attribute indicates whether a particular 1044 method is OPTIONAL or REQUIRED. Currently, STACIE only provides 1045 details for key derivation using passwords. Future specifications 1046 MAY extend this scheme to support common alternate, or additional 1047 methods, including second factor mechanisms, which is indicated by 1048 the presence of multiple method objects marked as REQUIRED. 1050 If a user or site specific salt value is available, it MUST be 1051 returned in the password object. The salt provides a non-secret 1052 random value which ensures independence between different uses of the 1053 same password at different points in time. The salt value is 1054 particularly important for sites with a policy of stripping the 1055 domain portion off usernames, as a unique salt will ensure 1056 independence between accounts with an identical username and 1057 password, but residing on different systems. 1059 The singular method defined by this specification is the password 1060 mechanism, which provides an object containing the following 1061 parameters specified below. 1063 *Required Parameters* 1065 username 1066 The username returns the normalized username in a form suitable 1067 for use as an input parameter to the cryptographic hash function. 1068 Presumably, this will involve matching the value provided by the 1069 client with a static username identifier to ensure a deterministic 1070 output. 1072 salt 1073 The salt provides additional entropy for the cryptographic hash 1074 function. The salt value SHOULD be randomly generated and unique 1075 for every username. A minimum of 64 octets SHOULD be returned, 1076 with additional octets allowed in 32 octet increments. Clients 1077 MUST be capable handling salt values up to 1,024 octets in length. 1079 nonce 1080 The nonce MUST be combined with the verification token, which 1081 results in the ephemeral login token. Server implementations MUST 1082 ensure a unique nonce is used for each authentication attempt. 1084 *Optional Parameters* 1086 bonus 1087 The bonus value mandates an arbitrary number of additional hash 1088 rounds a client MUST perform during each stage, in addition to the 1089 base rounds, and MAY be used by system operators to mitigate 1090 improvements in computing performance, or simply provide 1091 additional security sensitive accounts. Clients must accept and 1092 support values between 0 to 1,024. Implementations MAY provide 1093 support for values higher than 1,024. If this attribute is 1094 missing, a client MUST assume a default value of 0. 1096 hash 1097 The hash value provides an object which identifies the one-way 1098 hash function, along with any parameters specific to the supplied 1099 primitive. This specification defines the hash objects for the 1100 "sha2" and "skein" primitives. Clients MUST support the SHA2 1101 algorithm. Support for SHA3 or Skein is OPTIONAL. If the hash 1102 object is missing, a client SHOULD assume the SHA2 algorithm with 1103 block and digest attribute values of 512 bits. If a SHA2 or Skein 1104 object is returned without block or digest values, a client MUST 1105 assume the default value of 512 bits. 1107 cipher 1108 The cipher value provides an object which identifies the symmetric 1109 cipher used to encrypt and decrypt data retrieved from the server 1110 along with any algorithm specific parameters. This specification 1111 mandates that all implementations MUST be capable of supporting 1112 the "aes" primitive using the "gcm" block mode with a 256 bit key. 1113 If the cipher object is missing, clients MUST assume that AES 1114 [AES] is being used in the GCM [GCM] block mode, with a 256 bit 1115 key. These same default values MUST be used if the cipher object 1116 specifies AES, but lacks values for the mode and key attributes. 1118 disposition 1119 An enumerated value, with values of OPTIONAL and REQUIRED. If 1120 this value is missing, REQUIRED is presumed as the default value. 1122 If two or more method objects are marked as REQUIRED, then 2 1123 factor authentication is implied. 1125 *Example* 1127 { methods: 1128 [ password: 1129 { username: "user@example.tld", 1130 salt: "lyrtpzN8cBRZvsiHX6y4j-pJOjIyJeuw5aVXzrItw1G4EOa-6CA4R9Bh 1131 VpinkeH0UeXyOeTisHR3Ik3yuOhxbWPyesMJvfp0IBtx0f0uorb8wPnhw5BxD 1132 JVCb1TOSE50PFKGBFMkc63Koa7vMDj-WEoDj2X0kkTtlW6cUvF8i-M", 1133 nonce: "oDdYAHOsiX7Nl2qTwT18onW0hZdeTO3ebxzZp6nXMTo__0_vr_AsmAm 1134 3vYRwWtSCPJz0sA2o66uhNm6YenOGz0NkHcSAVgQhKdEBf_BTYkyULDuw2fSk 1135 bO7mlnxEhxqrJEc27ZVam6ogYABfHZjgVUTAi_SICyKAN7KOMuImL2g", 1136 bonus: "131072", 1137 hash: "sha2", 1138 cipher: "aes", 1139 disposition: "required" } 1140 ] 1141 } 1143 7.3. Password Authentication 1145 The process for a password based authentication concludes by 1146 submitting an "authenticate" request with an ephemeral login token. 1147 The response provides a keys array, with objects corresponding to the 1148 various realm specific keys specific to the protocol. These values 1149 are combined with the master key to derive the symmetric keys for the 1150 various realms used to encrypt data on a client. 1152 7.3.1. Authenticate Request 1154 The authenticate object is submitted to a server for validation. 1156 *Required Parameters* 1158 username 1159 The normalized username. 1161 nonce 1162 A randomly generated value, which MUST be combined with the 1163 verification token to create an ephemeral login token. Every 1164 nonce value MUST only be used for one authenticate request. 1165 Failed login attempts require a new nonce value to retry the login 1166 attempt. 1168 token 1169 The ephemeral login token needed to authenticate a session or 1170 token. 1172 *Example* 1174 { authenticate: 1175 { username: "user@example.tld", 1176 nonce: "oDdYAHOsiX7Nl2qTwT18onW0hZdeTO3ebxzZp6nXMTo__0_vr_AsmAm 1177 3vYRwWtSCPJz0sA2o66uhNm6YenOGz0NkHcSAVgQhKdEBf_BTYkyULDuw2fSk 1178 bO7mlnxEhxqrJEc27ZVam6ogYABfHZjgVUTAi_SICyKAN7KOMuImL2g", 1179 token: "-Eu5mUcA7ko2BysV965hrf9bvMlh_S_iiI3tfMr0Qc7hf4oPmBCdGOU 1180 9VCeQ1qBrga-WyR-rko5l0-feoWuuuA" 1181 } 1182 } 1184 7.3.2. Authenticate Response 1186 If the authentication attempt was successful the server will return 1187 an array of realm shards. 1189 *Required Parameters* 1191 index 1192 The an incrementing counter corresponding to each shard value. 1194 label 1195 A protocol specific string containing the realm where the key 1196 value is used. 1198 shard 1199 The random bytes which are combined with the master key to derive 1200 a realm specific key value. 1202 *Example* 1204 { realms: [ 1205 { index: "1", 1206 label: "mail", 1207 shard: "gD65Kdeda1hB2Q6gdZl0fetGg2viLXWG0vmKN4HxE3Jp3Z0Gkt5prqS 1208 mcuY2o8t24iGSCOnFDpP71c3xl9SX9Q", 1209 } 1210 ] 1211 } 1213 However, if the authentication request is unsuccessful and the server 1214 is willing to allow the client another attempt, it will return a 1215 login response with a unique nonce value. A nonce value MUST only be 1216 used once regardless of whether the attempt is successful. The 1217 following example only contains the required parameters. 1219 *Example* 1221 { methods: 1222 [ password: 1223 { username: "user@example.tld", 1224 salt: "lyrtpzN8cBRZvsiHX6y4j-pJOjIyJeuw5aVXzrItw1G4EOa-6CA4R9Bh 1225 VpinkeH0UeXyOeTisHR3Ik3yuOhxbWPyesMJvfp0IBtx0f0uorb8wPnhw5BxD 1226 JVCb1TOSE50PFKGBFMkc63Koa7vMDj-WEoDj2X0kkTtlW6cUvF8i-M", 1227 nonce: "vQmxYp9sznZJ1M62AxSGe3cQgMqTmVw92E1qfNR_Fl_u2zVFEiyV5dV 1228 2abGEhsWPDkHsxtJGj-NTEF1vet1mlgfD67mQO1IPG7RfxPmEAJwAWGWkbgPG 1229 kQI2tpfAs5LqQai-Any3I95Kq-eTPIP8ykQYXKW8qO-DJCw5SmmCrJs" } 1230 ] 1231 } 1233 Or if the server does not want to allow any further attempts to 1234 access the account, it MAY also return an error message. 1236 { error: "The authentication attempt failed." } 1238 7.4. Password Change 1240 Update the verification token, and salt values on the server. Note 1241 the salt value is only updated if user specific salt values are being 1242 used. Alter any existing realm specific shard values, and if 1243 required add new randomly generated realm specific shard values. 1245 7.5. Fetch Realm Shards 1247 Fetch the realm shard values. The result MAY be request a specific 1248 realm, and serial number. 1250 7.6. Add a Realm Shard 1252 Add a shard, for a given realm, to the account using the next 1253 available serial number. 1255 8. Security Considerations 1257 Client and server implementations SHOULD follow the recommendations 1258 provided here to avoid leakage, and improve difficulty. 1260 8.1. Servers 1262 *Username Enumeration* 1264 To avoid enumeration and avoid leaking the list of valid user 1265 accounts, servers SHOULD respond to authenticate requests with valid 1266 and invalid usernames in the same fashion. Because salt values are 1267 typically unavailable in this situation, servers SHOULD normalize and 1268 return the username along with a dynamically derived salt value 1269 generated by combining the username with a site specific value. This 1270 will ensure a consistent salt value is returned on subsequent 1271 requests for the same invalid username. Servers MAY choose to return 1272 an error if the username contains invalid characters, or was provided 1273 with an unrecognized domain name. 1275 *Salt Values* 1277 To ensure STACIE provides the maximum amount of protection, 1278 implementations SHOULD generate unique, random salt values for every 1279 user, and then rotate the salt value every time the password is 1280 updated. This will ensure independence between common inputs, and 1281 strengthen the security analysis underpinning the design [HKDF]. 1283 8.2. Clients 1285 *Side Channels* 1287 A properly implemented client SHOULD ensure it's impossible for an 1288 attacker to correlate the duration between client request/responses 1289 with the plain text password length. Several mitigation strategies 1290 are possible, including submitting authentication requests 1291 independently of when users input their password. Adding random 1292 delays between hash rounds, which are independent of system load and 1293 processor speed, or using a constant duration for password processing 1294 independent length, are also possible. Clients MAY round any 1295 artificial processing delays to aligned boundaries, which would also 1296 make correlation more difficult. 1298 8.3. Shared 1300 *Transport Security* 1302 STACIE implementations MUST support TLS using a ciphersuite capable 1303 of protecting against network eavesdroppers, data tampering and 1304 ensure the confidentiality of messages. Protocols incorporating 1305 STACIE as a component MUST provide recommendations sensitive to their 1306 intended context, but SHOULD encourage the use of TLS version 1.2, or 1307 later, and limit implementations to ciphersuites capable of providing 1308 perfect forward secrecy. Server deployments SHOULD ensure they 1309 provide valid TLS certificates, and client implementations SHOULD 1310 ensure they properly validate server certificates using the 1311 procedures described in RFC 6125 [TLS-PKIX] or optionally, using the 1312 procedures described in RFC 6698 [TLS-DANE]. 1314 As of this writing, the RECOMMENDED ciphersuite is 1315 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, identified by the octet values 1316 {0xC0, 0x30}, or the equivalent ECDSA variant, 1317 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, which is identified by the 1318 octet values {0xC0,0x2C}. [TLS-GCM] 1320 Specific requirements and recommendations will need to be updated 1321 over time, based on what is widely deployed, and MAY need altering 1322 based on future vulnerability discoveries. To obtain contemporary 1323 guidance, or find additional recommendations, implementers and system 1324 operators SHOULD consult the Recommendations for Secure Use of TLS 1325 and DTLS [TLS-UTA]. 1327 9. IANA Considerations 1329 This document has no actions for IANA. 1331 10. Feedback 1333 The preceding document was excreted with the assistance of a 1334 diarrhoetic. As such, feedback is both welcome, and encouraged. 1336 11. Acknowledgments 1338 The genesis for STACIE was the authentication and key derivation 1339 method used by Lavabit LLC to authenticate client connections and 1340 protect the user specific private keys. Improvements were made while 1341 adapting the original server based scheme to operate on clients being 1342 developed for the Privacy Respecting Internet Mail Environment 1343 (PRIME). The author would also like to acknowledge and thank the One 1344 Password Protocol [ONEPW] developed for Firefox Sync and the HKDF 1345 [HKDF] specification for inspiring some of the improvements 1346 incorporated into STACIE. 1348 The improvements were all focused on providing operational 1349 flexibility, extensibility, while improving the security 1350 characteristics of short, relatively simple passwords commonly chosen 1351 by bipedal hominids. Acknowledgment must also be given to the large 1352 online services which allowed their password databases to be publicly 1353 scrutinized. Analysis of these databases proved invaluable while 1354 selecting the constants used by STACIE, and allowed the author to see 1355 how variations effected the dynamic difficulty level for a random 1356 sampling of real passwords. 1358 The goal for STACIE was to ensure it provided sufficient resistance 1359 against brute force attacks for the vast majority of passwords which 1360 will inevitably be used. Admittedly the term "sufficient resistance" 1361 is very subjective, and is constantly being shifted by advances in 1362 technology. Thanks should be given to the critics. Their complaints 1363 led to a modular hash algorithm, and the strategy of combining a 1364 dynamically calculated difficulty with a policy based bonus. 1365 Hopefully these decisions will ensure the survival of users with 1366 short password who inevitably get stuck on the long tail. STACIE is 1367 not a substitute for long, truly random, and incredibly complex 1368 passwords used by any evolved hominids capable of remembering them. 1370 The author would also like to thank Stacie for inspiring the name. 1371 Her resistance to having a computer bear her name, inevitably, led to 1372 something far better. 1374 12. Normative References 1376 [AES] National Institute of Standards and Technology, "Advanced 1377 Encryption Standard (AES), FIPS 197", November 2001, 1378 . 1381 [BASE] Josefsson, S., "The Base16, Base32, and Base64 Data 1382 Encodings", October 2006, . 1385 [CAPITALIZATION] 1386 Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 1387 2119 Key Words", May 2017, . 1390 [GCM] Dworkin, M., "Recommendation for Block Cipher Modes of 1391 Operation: Galois/Counter Mode (GCM) and GMAC, SP 1392 800-38D", November 2007, 1393 . 1396 [HKDF] Krawczyk, H., "Cryptographic Extraction and Key 1397 Derivation: The HKDF Scheme", May 2010, 1398 . 1400 [HMAC] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed- 1401 Hashing for Message Authentication", February 1997, 1402 . 1404 [HMAC-FIPS] 1405 National Institute of Standards and Technology, "The 1406 Keyed-Hash Message Authentication Code (HMAC), FIPS 1407 198-1", July 2008, 1408 . 1411 [HMAC-SHA] 1412 Nystrom, M., "Identifiers and Test Vectors for HMAC-SHA- 1413 224, HMAC-SHA-256, HMAC-SHA-384, and HMAC-SHA-512", 1414 December 2005, . 1416 [JSON] Bray, T., "The JavaScript Object Notation (JSON) Data 1417 Interchange Format", December 2017, 1418 . 1420 [KEYWORDS] 1421 Bradner, S., "Key words for use in RFCs to Indicate 1422 Requirement Levels", March 1997, 1423 . 1425 [ONEPW] Boulange, R., "One Password Protocol", May 2014, 1426 . 1429 [PBH] National Institute of Standards and Technology, "SHA-3 1430 Standard: Permutation-Based Hash and Extendable-Output 1431 Functions, FIPS 202", August 2015, 1432 . 1434 [SHS] National Institute of Standards and Technology, "Secure 1435 Hash Standard, FIPS 180-2", August 2015, 1436 . 1439 [SKEIN] Ferguson, N., Lucks, S., Schneier, B., Whiting, D., 1440 Bellare, M., Kohno, T., Callas, J., and J. Walker, "The 1441 Skein Hash Function Family", November 2008, 1442 . 1445 [TLS-DANE] 1446 Hoffman, P. and J. Schlyter, "The DNS-Based Authentication 1447 of Named Entities (DANE) Transport Layer Security (TLS) 1448 Protocol: TLSA", August 2012, . 1451 [TLS-GCM] Rescorla, E., "TLS Elliptic Curve Cipher Suites with SHA- 1452 256/384 and AES Galois Counter Mode (GCM)", August 2008, 1453 . 1455 [TLS-PKIX] 1456 Saint-Andre, P. and J. Hodges, "Representation and 1457 Verification of Domain-Based Application Service Identity 1458 within Internet Public Key Infrastructure Using X.509 1459 (PKIX) Certificates in the Context of Transport Layer 1460 Security (TLS)", March 2011, . 1463 [TLS-UTA] Sheffer, Y., Holz, R., and P. Saint-Andre, 1464 "Recommendations for Secure Use of TLS and DTLS", February 1465 2015, . 1468 Appendix A. Test Vectors 1470 This appendix provides test vectors. Binary values are provided 1471 using the base64url encoding, with line breaks added as necessary. 1473 A.1. Inputs 1475 # User Inputs 1476 password = "password" 1477 username = "user@example.tld" 1479 # Server Inputs 1480 bonus = 131072 1481 salt = "lyrtpzN8cBRZvsiHX6y4j-pJOjIyJeuw5aVXzrItw1G4EOa-6CA4R" \ 1482 "9BhVpinkeH0UeXyOeTisHR3Ik3yuOhxbWPyesMJvfp0IBtx0f0uorb8w" \ 1483 "Pnhw5BxDJVCb1TOSE50PFKGBFMkc63Koa7vMDj-WEoDj2X0kkTtlW6cU" \ 1484 "vF8i-M" 1485 nonce = "oDdYAHOsiX7Nl2qTwT18onW0hZdeTO3ebxzZp6nXMTo__0_vr_" \ 1486 "AsmAm3vYRwWtSCPJz0sA2o66uhNm6YenOGz0NkHcSAVgQhKdEBf_BT" \ 1487 "YkyULDuw2fSkbO7mlnxEhxqrJEc27ZVam6ogYABfHZjgVUTAi_SICy" \ 1488 "KAN7KOMuImL2g" 1490 # Realm Inputs 1491 realm = "mail" 1492 shard = "gD65Kdeda1hB2Q6gdZl0fetGg2viLXWG0vmKN4HxE3Jp3Z" \ 1493 "0Gkt5prqSmcuY2o8t24iGSCOnFDpP71c3xl9SX9Q" 1495 # Encrypted Data 1496 encrypted_data = "AACS5PQoBg4ON1Xt6aUSddMxTTIKGdbGSelUkIbUkUj" \ 1497 "prZv9ekAwPRrJOUqJqWGhdgEvCzSkZwr-kvNZo6f2IW1a 1499 A.2. Outputs 1501 rounds = 196608 1502 seed = "5f-3mTGTSf-sFPfMkGqHTyydDjJU-cqahwDmHWyh6DLQ2oLBlz3ht" \ 1503 "PTZS6V-TYVBiwJxuTYmQv3fCZN3Fb8brg" 1505 master_key = "SDt67ZfTr8c1KO1Ym6BI69i7TQNNq5J2irym6gPQlEo0MGc" \ 1506 "5x-b43bi1uXJDF4rhJJvfl9NFBQkDQ_X_2n66RA" 1507 password_key = "lYmvC3qutKIb6QrnxnTi_WuJR_PSiyMZ0CdH18DAxHIgw" \ 1508 "jj0_e4W6X8bKckKNGugWMMXmNgXDYb_7LlvtfN3HQ" 1510 verification_token = "-Eu5mUcA7ko2BysV965hrf9bvMlh_S_iiI3tfMr" \ 1511 "0Qc7hf4oPmBCdGOU9VCeQ1qBrga-WyR-rko5l0-feoWuuuA" 1512 ephemeral_login_token = "8YEH_6kBdAdR5vlBaxs3KR3pZ429bEzF3AVF" \ 1513 "hkA0P2WPt2h94omJq-d8NhX0rNLBESn2yTu_z0ugJcSVLyz5iQ" 1515 realm_key = "v53LS2JFjE-ErqJ2UWTe0O-dYxtYMUQzevxXczVVkQzcRPSS" \ 1516 "4sdBHPaKBniqxxr7SWaQR3moXN2tzJJhJ_p5Dw" 1518 tag_key = "751jG1gxRDN6_FdzNVWRDA" 1519 vector_key = "v53LS2JFjE-ErqJ2UWTe0A" 1520 cipher_key = "3ET0kuLHQRz2igZ4qsca-0lmkEd5qFzdrcySYSf6eQ8" 1522 decrypted_data = "Attack at dawn!" 1524 Author's Address 1526 Ladar Levison 1527 Lavabit LLC 1529 Email: ladar@lavabit.com