SAAG A. Bouchez Internet-Draft Tranquil IT SAS Intended status: Standards Track 21 November 2025 Expires: 25 May 2026 SCRAM with Modular Crypt Format (SCRAM-MCF) draft-bouchez-scram-mcf-00 Abstract This document specifies SCRAM-MCF, an extension to the Salted Challenge Response Authentication Mechanism (SCRAM) family of SASL mechanisms ([RFC5802]) and HTTP Digest extensions ([RFC7616], [RFC7677]). The extension replaces the PBKDF2-specific iteration count attributes i= and s= in the server-first-message with a generic Modular Crypt Format (MCF) descriptor mcf=. This allows servers to use modern memory-hard key derivation functions such as Argon2, SCrypt, or bcrypt while preserving the full security properties and message flow of SCRAM. The change is fully backward compatible: servers can continue sending i= and s= for legacy clients and only send mcf= (or both) when the client advertises support. Status of This Memo This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79. Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet- Drafts is at https://datatracker.ietf.org/drafts/current/. Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress." This Internet-Draft will expire on 25 May 2026. Copyright Notice Copyright (c) 2025 IETF Trust and the persons identified as the document authors. All rights reserved. Bouchez Expires 25 May 2026 [Page 1] Internet-Draft SCRAM-MCF November 2025 This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/ license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Revised BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Revised BSD License. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 2 2. Conventions and Terminology . . . . . . . . . . . . . . . . . 3 3. SCRAM-MCF Extension . . . . . . . . . . . . . . . . . . . . . 3 3.1. Client Capability Advertisement . . . . . . . . . . . . . 3 3.2. Server-first-message Changes . . . . . . . . . . . . . . 3 3.3. Client Processing Rules . . . . . . . . . . . . . . . . . 4 3.4. SCRAM-MCF Algorithm Overview . . . . . . . . . . . . . . 4 3.5. Server Storage Recommendation . . . . . . . . . . . . . . 5 4. Formal ABNF Changes (augmented from RFC 5802) . . . . . . . . 5 5. Security Considerations . . . . . . . . . . . . . . . . . . . 6 5.1. Preservation of the SCRAM Proof Construction . . . . . . 6 5.2. Using MCF-Derived Outputs as HMAC Keys . . . . . . . . . 6 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 7 7. Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . 7 8. SCRAM Authentication Exchange . . . . . . . . . . . . . . . . 7 9. Normative References . . . . . . . . . . . . . . . . . . . . 8 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 8 1. Introduction SCRAM as defined in [RFC5802] and its SHA-256 variant in [RFC7677] is widely deployed (PostgreSQL, MongoDB, Kafka, SASL libraries, etc.). Its only key derivation function is PBKDF2-HMAC-SHA-1 or PBKDF2-HMAC- SHA-256. PBKDF2 is no longer considered state-of-the-art against GPU/ASIC-based password cracking. Modern password hashing algorithms (Argon2 – winner of the 2015 Password Hashing Competition, SCrypt, bcrypt) are memory-hard and far more resistant to parallel brute-force attacks. However, replacing SCRAM entirely with a new mechanism is unnecessary: the core proof- of-possession construction of SCRAM is excellent. Only the key derivation step needs to become negotiable. This document defines the smallest possible standards-compliant extension that achieves exactly that. Bouchez Expires 25 May 2026 [Page 2] Internet-Draft SCRAM-MCF November 2025 2. Conventions and Terminology The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. The term "Modular Crypt Format" (MCF) refers to the de-facto standard string format used by crypt(3), Passlib, Spring Security, and most modern password hashing libraries. Examples: $argon2id$v=19$m=65536,t=2,p=4$z8e0jsE2kz7z6...$7KX4Wm6Q7f... $scrypt$ln=16,r=8,p=1$z8e0jsE2kz7z6uL0m4zZ6Q$7KX4Wm6Q7... $2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2KdeeWLuGmsfGlMfOxih58VYVfxe 3. SCRAM-MCF Extension 3.1. Client Capability Advertisement A client that implements SCRAM-MCF MUST include the attribute mcf- support=1 in the reserved extension field of the client-first-message when using any SCRAM mechanism that supports this extension. Example (client-first-message): n,,n=user,r=fyko+d2lbbFgONRv9qkxdawL,mcf-support=1 Clients that do not send mcf-support=1 MUST be treated exactly as in the original SCRAM algorithm (legacy clients). They MUST NOT support the mcf= attribute if they did not send mcf-support=1 first. 3.2. Server-first-message Changes A server that receives mcf-support=1 and wishes to use a modern KDF MUST respond with the attribute mcf= instead of i= and s=. The value of mcf= is the full MCF identifier string up to but not including the final stored hash part, encoded as base-64. In other words: everything up to and including the base64-encoded salt and its trailing $ character (if any), then converted to base-64. The MCF identifier MUST be converted to base-64, to ensure no commas signs appear in the attribute value. Valid examples of MCF identifiers: Bouchez Expires 25 May 2026 [Page 3] Internet-Draft SCRAM-MCF November 2025 $argon2id$v=19$m=65536,t=2,p=4$z8e0jsE2kz7z6uL0m4zZ6Q$ $scrypt$ln=16,r=8,p=1$z8e0jsE2kz7z6uL0m4zZ6Q$ $2a$06$m0CrhHm10qJ3lXRY.5zDGO Values transmitted as mcf= attribute, after base-64 encoding: mcf=JGFyZ29uMmlkJHY9MTkkbT02NTUzNix0PTIscD00JHo4ZTBqc0Uya3o3ejZ1... mcf=JHNjcnlwdCRsbj0xNixyPTgscD0xJHo4ZTBqc0Uya3o3ejZ1TDBtNHpaNlEk mcf=JDJhJDA2JG0wQ3JoSG0xMHFKM2xYUlkuNXpER08= Backward compatibility fallback: If the server cannot or does not want to use MCF, it simply omits mcf= and sends the normal i= and s= attributes. 3.3. Client Processing Rules * If the server-first-message contains mcf=, the client MUST ignore any i= and s= attributes and MUST use the specified MCF string, after proper base-64 decoding, to derive SaltedPassword exactly as if it were calling the standard password-to-key function of that algorithm with the cleartext password and the MCF parameters/salt. * The full encoded output of this MCF KDF, including its identifier, parameters, salt and checksum, MUST become the SaltedPassword as in [RFC5802] Section 3. * The rest of the protocol (ClientKey, ServerKey, AuthMessage, ClientProof, etc.) is unchanged. * The H() and HMAC() functions used to compute the client and server proofs MUST follow the SASL negotiation, e.g. SHA-256 and HMAC- SHA-256 for "SCRAM-SHA-256" or SHA-512 and HMAC-SHA-512 for "SCRAM-SHA-512". * If the client does not recognize or support the MCF identifier, it MUST respond with a SASL/HTTP error (e.g., "invalid-parameters"). 3.4. SCRAM-MCF Algorithm Overview The following is a description of the algorithms used in a full, uncompressed SASL SCRAM-MCF authentication exchange. Bouchez Expires 25 May 2026 [Page 4] Internet-Draft SCRAM-MCF November 2025 // SCRAM-MCF password KDF SaltedPassword = MCF(Password, identifier, parameters, salt) // using MCF prefix identifier, parameters and salt // e.g. "$2a$06$m0CrhHm10qJ3lXRY.5zDGO3rS2Kd..." // initial server storage ClientKey := HMAC(SaltedPassword, "Client Key") StoredKey := H(ClientKey) ServerKey := HMAC(SaltedPassword, "Server Key") persist the MCF prefix, StoredKey and ServerKey in the DB // client ClientKey := HMAC(SaltedPassword, "Client Key") ClientSignature := HMAC(StoredKey, AuthMessage) return ClientProof := ClientKey XOR ClientSignature // server ClientSignature := HMAC(StoredKey, AuthMessage) CandidateClientKey := ClientProof XOR ClientSignature Checks: H(CandidateClientKey) == StoredKey return ServerProof := HMAC(ServerKey, AuthMessage) // client verifies ServerSignature := ServerProof XOR ClientSignature Checks: ServerSignature == HMAC(ServerKey, AuthMessage) The rest of these messages is defined in [RFC5802] Section 7. 3.5. Server Storage Recommendation Servers MUST store the MCF prefix string (identifier + parameters + salt) for each user. For security reasons, the MCF checksum part MUST NOT be persisted; instead, the SCRAM-derived StoredKey and ServerKey MUST be stored. Servers MAY store and accept other SCRAM hashes (e.g., SCRAM-SHA-1 or SCRAM-SHA-256) for backward compatibility. But restricting to the safest algorithms (like SCRAM-MCF) is strongly recommended. 4. Formal ABNF Changes (augmented from RFC 5802) Bouchez Expires 25 May 2026 [Page 5] Internet-Draft SCRAM-MCF November 2025 server-first-message = ( scram-attr-val "," )* "r=" nonce [ "," "s=" base64 ] [ "," "i=" posint ] [ "," "mcf=" mcf-base64 ] *( "," scram-extension ) mcf-base64 = base64( mcf-descriptor ) mcf-descriptor = "$" mcf-id "$" mcf-params "$" base64-salt [ "$" ] mcf-id = "argon2i" / "argon2d" / "argon2id" / "scrypt" / "2b" / other registered identifiers 5. Security Considerations 5.1. Preservation of the SCRAM Proof Construction In respect to the standard SCRAM mechanism, this SCRAM-MCF extension could be evaluated as such: * The extension preserves channel binding, proof-of-possession, and mutual authentication exactly as in SCRAM. * Memory-hard KDFs dramatically increase the cost of offline dictionary attacks. * Because the KDF identifier and parameters are sent in the clear (as in standard SCRAM with i=), no new information is leaked to an eavesdropper. * Thanks to the MCF registration mechanism, this SCRAM-MCF pattern was designed to be future-proof. * Clients and servers MUST enforce minimum work factors (e.g., reject Argon2 with m<32 MiB or t<2) to avoid downgrade attacks if the server is compromised. * Weaker "SCRAM-SHA-1" MUST be rejected when used with the mcf= extension. 5.2. Using MCF-Derived Outputs as HMAC Keys As defined above, ClientKey and ServerKey are computed using HMAC() on the MCF output. The length and structure of this value differ from PBKDF2, as used in classic SCRAM. HMAC constructions (including HMAC-SHA-256 and HMAC-SHA-512 refered by this document) are provably secure even when the supplied key is long or non-uniform. Per Bellare, Canetti, and Krawczyk (1997; 2006), HMAC guarantees pseudorandomness provided that: Bouchez Expires 25 May 2026 [Page 6] Internet-Draft SCRAM-MCF November 2025 * keys longer than the hash function block size are reduced by hashing (as mandated by HMAC), and * keys of arbitrary internal structure are permitted. Thus, MCF outputs — even if longer than a SHA-2 block — are acceptable and safe HMAC keys. Because memory-hard KDFs generate outputs indistinguishable from random to an attacker lacking the password, the resulting SaltedPassword is at least as strong as the PBKDF2-derived SaltedPassword in classic SCRAM. Therefore, replacing PBKDF2 output with memory-hard KDF output does not weaken the HMAC-based authentication proofs of SCRAM. 6. IANA Considerations This document requests IANA registration of the SASL/GS2 extension attribute mcf-support and the server-first-message attribute mcf. No new SASL mechanism name ("SCRAM-MCF-*") needs to be registered. The existing names "SCRAM-SHA-256", "SCRAM-SHA-256-PLUS", "SCRAM-SHA- 512", etc. continue to identify the underlying H() and HMAC() functions used for the proof calculation. 7. Acknowledgments The idea of using Modular Crypt Format inside a SCRAM-like flow was first implemented by the author in the Synopse mORMot 2 Framework in 2025 and standardized as the wire-level extension described in this document. The author would like to thank the PostgreSQL, MongoDB, and SASL communities for their prior art and feedback on modernizing password hashing in authentication protocols. 8. SCRAM Authentication Exchange This is a simple example of a SCRAM-SHA-256 authentication exchange when the client doesn't support channel bindings (username 'user' and password 'pencil' are used, with SCrypt MCF hashing): C: n,,n=user,r=rOprNGfwEbeRWgbNEkqO,mcf-support=1 S: r=rOprNGfwEbeRWgbNEkqO%hvYDpWUa2RaTCAfuxFIlj)hNlF$k0,mcf= JHNjcnlwdCRsbj00LHI9OCxwPTEkUU54NE40NTRwcE1lS21Eanh5cmhzaDdRL1BZQlF3JA== C: c=biws,r=rOprNGfwEbeRWgbNEkqO%hvYDpWUa2RaTCAfuxFIlj)hNlF$k0, p=e9kbO4Xa0PN8VWHHboGkVt3AF0qMB07EJcjWkueKnxA= S: v=6TR/nuhTSs1/eGf7YeoN5696momPErG5RSAZ9gpZtQU= Bouchez Expires 25 May 2026 [Page 7] Internet-Draft SCRAM-MCF November 2025 The corresponding MCF prefix string is "$scrypt$ln=4,r=8,p=1$QNx4N454ppMeKmDjxyrhsh7Q/PYBQw$", which is base-64 encoded in the mcf= attribute above. 9. Normative References [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", March 1997, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", May 2017, . [RFC5802] Newman, C., Menon, A., Hildebrand, J., and K. Zeilenga, "Salted Challenge Response Authentication Mechanism (SCRAM) SASL and GSS-API Mechanisms", July 2010, . [RFC7677] Hansen, T. and A. Melnikov, "SCRAM-SHA-256 and SCRAM-SHA- 256-PLUS SASL Mechanisms", November 2015, . [RFC7616] Fielding, R. and J. F. Reschke, "HTTP Digest Access Authentication", September 2015, . Author's Address Arnaud Bouchez Tranquil IT SAS 12 Avenue Jules Verne 44230 Saint-Sebastien-sur-Loire France Email: abouchez@tranquil.it Bouchez Expires 25 May 2026 [Page 8]