| Internet-Draft | SIP Digest Public-Key Authentication | May 2026 |
| Sobolyev | Expires 30 November 2026 | [Page] |
This document defines three Session Initiation Protocol (SIP) Digest authentication algorithms that replace password-derived Digest secrets with public-key-based authentication material. Two algorithms derive a response secret from an X25519 shared secret, and one algorithm uses a Fiat-Shamir Schnorr proof over the ristretto255 group.¶
The mechanisms defined here preserve the existing SIP Digest challenge and authorization header flow while adding Digest parameters that carry public keys and, optionally, an authenticated server challenge proof.¶
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 30 November 2026.¶
Copyright (c) 2026 IETF Trust and the persons identified as the document authors. All rights reserved.¶
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.¶
This document defines the following SIP Digest authentication algorithm tokens:¶
The algorithms are intended for deployments where the User Agent Client (UAC) and User Agent Server (UAS), or a proxy acting as the authenticating server, have pre-provisioned trust in each other's public keys. They do not define certificate discovery, enrollment, or authorization policy.¶
The X25519 algorithms derive authentication material from the shared secret computed by [RFC7748] X25519. The ristretto255 algorithm uses a Schnorr-style non-interactive proof over the group defined by [RFC9496].¶
X25519-HKDF-SHA256 and X25519-HMAC-SHA256 preserve
the original SIP Digest flow: the UAS sends a challenge and the UAC sends
an authorization response after validating the challenged server public
key against local policy. R25519-SCHNORR-SHA256 adds a new
capability: the UAC can request that the UAS pre-authenticate the
challenge using server-response before the UAC generates its own
proof. This prevents an unauthenticated man-in-the-middle attacker from
causing the UAC to perform private-key operations for attacker-generated
challenges, reducing exposure to private-key extraction attempts that rely
on side channels or fault behavior during proof generation.¶
The existing SIP Digest parameters, including realm,
username, nonce, uri, qop,
nc, cnonce, and response, retain their
existing Digest roles. This document defines four new Digest
parameters: server-pubkey, client-pubkey,
client-challenge, and server-response.¶
Traditional SIP Digest authentication is based on a
username and a shared password or password-equivalent secret.
This model is well suited to human subscriber authentication and legacy
provisioning systems, but it is a poor fit for many machine-to-machine
SIP deployments.¶
Machine-to-machine SIP authentication is often performed between systems, services, trunks, gateways, proxies, application servers, Session Border Controllers (SBCs), and other automated endpoints. These entities do not always naturally correspond to human usernames and passwords. Password-based provisioning also creates operational issues: shared secrets must be generated, distributed, rotated, stored, and protected by both sides. A compromise of the verifier-side secret database can expose password-equivalent material that can be used for impersonation.¶
Public-key authentication is often a better fit for these environments. Each endpoint can be provisioned with a private key and a corresponding trusted public key. The private key does not need to be shared with the peer, and the public key can be distributed through configuration, inventory, orchestration, certificates, or another trust-management system.¶
The mechanisms in this document use modern elliptic-curve primitives rather than older RSA-based public-key schemes. X25519 and ristretto255 provide compact public keys and authentication material, efficient constant-time implementations, and simpler fixed-size encodings. These properties are useful for SIP deployments where authentication data is carried in header fields and where endpoints may need to perform many authentication operations per second.¶
The goal of these mechanisms is to support deployments where authorization is tied to possession of a configured private key rather than knowledge of a shared password, while preserving SIP Digest processing. This model also supports deployments where a request is not accepted merely because it arrives from a particular network, IP address, interface, trunk, or transport path. Instead, the receiver verifies cryptographic proof that the sender possesses the private key corresponding to a trusted public key, and then applies local authorization policy for that key, realm, endpoint, account, route, or service.¶
SIP over TLS can provide transport confidentiality, transport
integrity, and transport-layer peer authentication. However, TLS
authentication is tied to the transport connection and does not by itself
define SIP Digest identities, Digest realm scoping, SIP
authorization policy, or authentication of individual SIP requests and
entity bodies through the Digest qop model. The mechanisms in
this document are therefore complementary to TLS rather than replacements
for it.¶
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.¶
uri parameter.¶
qop=auth-int
calculation.¶
The parameters in this section extend the Digest
auth-param syntax used by SIP Digest authentication
[RFC3261] [RFC8760]. Unless otherwise
stated, each value is carried as a quoted string containing an unpadded
base64url value.¶
base64url-char = ALPHA / DIGIT / "-" / "_" base64url-value = 1*base64url-char b64q = DQUOTE base64url-value DQUOTE server-pubkey = "server-pubkey" EQUAL b64q client-pubkey = "client-pubkey" EQUAL b64q client-challenge = "client-challenge" EQUAL b64q server-response = "server-response" EQUAL b64q¶
ALPHA, DIGIT, and DQUOTE are defined by
[RFC5234]. EQUAL is inherited from the SIP
grammar in [RFC3261].¶
The server-pubkey parameter is sent by the UAS in
WWW-Authenticate, or by a proxy in
Proxy-Authenticate.¶
For X25519-HKDF-SHA256 and
X25519-HMAC-SHA256, it contains the raw 32-octet X25519 public
key of the authenticating server. For
R25519-SCHNORR-SHA256, it contains the 32-octet ristretto255
public key of the authenticating server.¶
A UAC receiving this parameter MUST verify that the decoded public key is trusted for the challenged SIP realm, peer, route, outbound proxy, or configured authentication domain before generating an authorization response.¶
The client-pubkey parameter is sent by the UAC in
Authorization or Proxy-Authorization.¶
For X25519-HKDF-SHA256 and
X25519-HMAC-SHA256, it contains the raw 32-octet X25519 public
key of the authenticating client. For
R25519-SCHNORR-SHA256, it contains the 32-octet ristretto255
public key whose corresponding private scalar is proven by the UAC.¶
A UAS receiving this parameter MUST verify that the
decoded public key is trusted for the claimed username, if
present, and realm. If username is absent, the UAS
MUST verify that client-pubkey is trusted for
the realm and for the applicable account, subscriber,
endpoint, authorization identity, or other local authorization
record.¶
The client-challenge parameter is sent by the UAC in an
initial Authorization or Proxy-Authorization header
when requesting an authenticated server challenge. It contains at least
128 bits of client-generated randomness.¶
The parameter is used by R25519-SCHNORR-SHA256 to allow the
UAS to prove possession of the private scalar corresponding to
server-pubkey in the 401 or 407 challenge response. The UAS
MUST NOT echo client-challenge in
WWW-Authenticate or Proxy-Authenticate.¶
The UAC MUST verify server-response using
the locally remembered client-challenge value that it generated
and sent. The UAC MUST NOT use any reflected or received
client-challenge value from a response header when verifying
server-response.¶
The server-response parameter is sent by the UAS in
WWW-Authenticate, or by a proxy in
Proxy-Authenticate, when responding to a request that contained
client-challenge.¶
The value is base64url(R || s), where R is a
compressed ristretto255 commitment of 32 octets and s is a
canonical scalar modulo the ristretto255 group order, encoded as 32
octets. The decoded value is therefore exactly 64 octets.¶
All cryptographic transcripts defined by this document use the following deterministic encoding to avoid ambiguity between adjacent SIP and Digest fields.¶
Transcript(label, field-list) is the octet string formed by
concatenating the US-ASCII label, a line feed
(%x0A), and then, for each field in order:¶
%x3A),¶
Unless otherwise stated, SIP and Digest string fields are encoded exactly as their field values appear after Digest quoted-string unescaping. Binary fields, including public keys, shared secrets, commitments, scalars, and hash outputs, are encoded as their raw octets when they are transcript fields. The final line feed is part of the transcript.¶
For qop=auth, the body-hash transcript field is the
zero-length value. For qop=auth-int, it is the raw 32-octet
SHA-256 digest of the entity body.¶
The Digest fields realm, username, nonce,
uri, qop, nc, cnonce, and
response retain their usual meanings in SIP Digest
authentication, except as explicitly stated in this section. For all
algorithms in this document, realm is REQUIRED
and qop=auth and qop=auth-int are supported.¶
For the algorithms defined by this document, username is
OPTIONAL. For all calculations and transcripts defined by
this document, an absent username is equivalent to an explicitly
empty username. All formulas that reference username use the
received username value if present, or a zero-length string if absent.¶
If username is present, it is an identity hint. The verifier
MAY use it to select an account, subscriber, endpoint, or
authorization record. The verifier MUST still verify that
client-pubkey is trusted for the claimed username and
realm. If username is absent, the verifier
MUST identify the peer by client-pubkey and
realm using local policy.¶
When qop=auth-int is used, the authentication calculation
includes the entity-body hash. For SIP INVITE requests carrying
Session Description Protocol (SDP), this provides integrity protection for
the SDP body against attackers that cannot produce the required
authentication response.¶
The response value is algorithm-specific. The
X25519-HKDF-SHA256 and X25519-HMAC-SHA256 algorithms
encode response as lowercase hexadecimal. The
R25519-SCHNORR-SHA256 algorithm uses a different format:
response is an unpadded base64url encoding of the 64-octet
Schnorr proof R_c || s_c.¶
The UAS sends a Digest challenge with
algorithm=X25519-HKDF-SHA256 and
server-pubkey.¶
The UAC sends a Digest authorization response with
client-pubkey. The username parameter
MAY be omitted.¶
Example with username present:¶
Example with username absent:¶
The UAC computes Z = X25519(client-private-key,
server-pubkey). The UAS computes Z =
X25519(server-private-key, client-pubkey). Both sides
MUST reject the exchange if the computed X25519 shared
secret is the all-zero value.¶
The Digest response key K is derived with HKDF-SHA256
[RFC5869]:¶
salt = Transcript("SIP-Digest-X25519-HKDF-SHA256-salt-v1",
nonce, cnonce)
info = Transcript("SIP-Digest-X25519-HKDF-SHA256-info-v1",
algorithm, username, realm, nonce, cnonce,
server-pubkey, client-pubkey)
K = HKDF-SHA256(IKM = Z, salt = salt, info = info, L = 32)
¶
The response value is computed as follows:¶
body-hash = "" ; for qop=auth
body-hash = SHA-256(entity-body) ; for qop=auth-int
HA1 = SHA-256(Transcript(
"SIP-Digest-X25519-HKDF-SHA256-HA1-v1",
username, realm, K))
HA2 = SHA-256(Transcript(
"SIP-Digest-X25519-HKDF-SHA256-HA2-v1",
method, digest-uri, qop, body-hash))
response = SHA-256(Transcript(
"SIP-Digest-X25519-HKDF-SHA256-response-v1",
HA1, nonce, nc, cnonce, qop, HA2))
¶
The response value is encoded as lowercase hexadecimal
SHA-256 output.¶
The X25519-HMAC-SHA256 algorithm uses the same
server-pubkey and client-pubkey parameters as
X25519-HKDF-SHA256, but computes the final response as
an HMAC [RFC2104] rather than as a Digest-style hash
chain.¶
The UAS sends a Digest challenge with
algorithm=X25519-HMAC-SHA256 and
server-pubkey.¶
The UAC sends a Digest authorization response with
client-pubkey. The username parameter
MAY be omitted.¶
Example with username present:¶
Example with username absent:¶
The UAC computes Z = X25519(client-private-key,
server-pubkey). The UAS computes Z =
X25519(server-private-key, client-pubkey). Both sides
MUST reject the exchange if the computed X25519 shared
secret is the all-zero value.¶
K = SHA-256(Transcript(
"SIP-Digest-X25519-HMAC-SHA256-key-v1",
Z, algorithm, username, realm, nonce, cnonce,
server-pubkey, client-pubkey))
¶
body-hash = "" ; for qop=auth
body-hash = SHA-256(entity-body) ; for qop=auth-int
transcript = Transcript(
"SIP-Digest-X25519-HMAC-SHA256-response-v1",
username, realm, nonce, nc, cnonce, qop,
method, digest-uri, body-hash, server-pubkey, client-pubkey)
response = HMAC-SHA256(K, transcript)
¶
The response value is encoded as lowercase hexadecimal
HMAC-SHA256 output.¶
The R25519-SCHNORR-SHA256 algorithm defines a
Schnorr-style Fiat-Shamir non-interactive proof of knowledge over the
ristretto255 group. The UAC proves knowledge of a scalar x_c
corresponding to client-pubkey = x_c * G, where G is
the canonical ristretto255 base point.¶
A UAC MAY request an authenticated server challenge
by including client-challenge in an initial request.¶
This header does not authenticate the UAC. It only supplies
freshness for an authenticated server challenge. A UAC that sends
client-challenge MUST remember the value locally
until it receives and verifies the corresponding
WWW-Authenticate or Proxy-Authenticate challenge, or
until the transaction is abandoned.¶
The UAS sends a Digest challenge with
algorithm=R25519-SCHNORR-SHA256 and
server-pubkey. If the request contained a valid
client-challenge, the UAS MAY include
server-response.¶
When server-response is present, it proves possession of
the private scalar corresponding to server-pubkey. The UAS has
private scalar x_s and public key A_s = x_s * G,
where A_s is server-pubkey.¶
T_srv_chal = Transcript(
"SIP-Digest-R25519-SCHNORR-SHA256-ServerChallenge-v1",
algorithm, method, digest-uri, realm, nonce, qop-list,
server-pubkey, client-challenge)
R_s = r_s * G
c_s = SHA-256(Transcript(
"SIP-Digest-R25519-SCHNORR-SHA256-ServerChallenge-c-v1",
T_srv_chal, R_s)) mod L
s_s = r_s + c_s * x_s mod L
server-response = base64url(R_s || s_s)
¶
r_s is a fresh random scalar and L is the
ristretto255 group order. The UAC verifies by recomputing the
transcript and checking s_s * G == R_s + c_s * A_s.¶
The UAC MUST reject the challenge if
server-response is required by local policy and is absent,
malformed, invalid, not bound to the locally remembered
client-challenge, or not valid for the received
server-pubkey.¶
The UAC sends a Digest authorization response with
client-pubkey. The username parameter
MAY be omitted. The response parameter
contains base64url(R_c || s_c), where R_c is a
compressed ristretto255 commitment and s_c is a canonical
scalar modulo the group order. This differs from the hexadecimal
Digest response values used by the X25519 algorithms. The decoded
value is exactly 64 octets.¶
A_c = x_c * G
R_c = r_c * G
body-hash = "" ; for qop=auth
body-hash = SHA-256(entity-body) ; for qop=auth-int
T_uac = Transcript(
"SIP-Digest-R25519-SCHNORR-SHA256-UAC-v1",
algorithm, username, realm, nonce, nc, cnonce, qop,
method, digest-uri, body-hash, server-pubkey, client-pubkey)
c_c = SHA-256(Transcript(
"SIP-Digest-R25519-SCHNORR-SHA256-UAC-c-v1",
T_uac, R_c)) mod L
s_c = r_c + c_c * x_c mod L
response = base64url(R_c || s_c)
¶
The UAS decodes A_c from client-pubkey,
reconstructs T_uac from the received request and Digest
parameters, and accepts only if s_c * G == R_c + c_c * A_c.
The UAS MUST reject malformed ristretto255 encodings,
non-canonical scalars, invalid proof lengths, and proofs that are not
valid for the exact received transcript.¶
A proof generated for one method, URI, nonce, cnonce, nonce-count, qop value, body, realm, server public key, client public key, or username value MUST NOT be accepted for another.¶
A receiver MUST reject authentication if any of the following are true:¶
server-pubkey is absent from the challenge;¶
client-pubkey is absent from the authorization response;¶
realm is absent from the challenge or authorization
response;¶
nonce is expired, unknown, malformed, or already
consumed;¶
nc does not increase monotonically for the nonce and client
identity pair;¶
cnonce is absent when qop is present;¶
qop is unsupported;¶
response is malformed; or¶
response does not match or verify against the locally
computed value.¶
For R25519-SCHNORR-SHA256, a receiver
MUST also reject authentication if
server-response is malformed when present, is absent when
required by local policy, or does not verify against the locally
remembered client-challenge.¶
A UAS MUST NOT authenticate a UAC merely because
client-pubkey is present. The client-pubkey value
MUST be bound to a trusted identity, such as the
username if present, configured endpoint, account, subscriber,
realm, or equivalent local authorization record.¶
A UAC MUST NOT answer a challenge merely because
server-pubkey is present. The server-pubkey value
MUST be present in the UAC's trusted key list for the
challenged peer, realm, outbound proxy, or service domain.¶
Implementations MUST reject algorithm identifiers other than those explicitly defined by this document or locally configured for this mechanism.¶
The UAS MUST generate nonces with sufficient entropy
and unpredictability. The UAS MUST reject replayed tuples
of client-pubkey, nonce, nc, and
cnonce. If username is present, the UAS
MAY also include username in the replay cache
key. The UAS SHOULD expire nonces after a short interval
and SHOULD bind nonces to the challenged realm, selected
algorithm, and server-pubkey.¶
The UAC SHOULD generate a fresh
client-challenge for each initial authenticated challenge
request. The UAC MUST NOT accept a
server-response generated for a different
client-challenge.¶
When qop=auth-int is used, the entity-body hash is included
in the authentication calculation. For SIP requests carrying SDP, this
protects the SDP body against modification by an attacker that does not
know the X25519-derived authentication secret or cannot generate the
required ristretto255 Schnorr proof.¶
If intermediaries are expected to modify the SDP body,
qop=auth-int can fail unless the modification happens before the
UAC computes the authorization response or unless the deployment
explicitly permits such behavior.¶
This document requests registration of the following Digest algorithm tokens in the applicable Digest algorithm registry:¶
The following Digest authentication parameters are also defined by
this document: server-pubkey, client-pubkey,
client-challenge, and server-response.¶
Implementations SHOULD use well-reviewed cryptographic libraries for X25519, HKDF-SHA256, HMAC-SHA256, SHA-256, and ristretto255. Implementations SHOULD avoid accepting algorithm aliases.¶
Implementations SHOULD domain-separate every proof or MAC input exactly as specified.¶
Implementations SHOULD log authentication failures without logging private keys, shared secrets, raw proof scalars, derived keys, or complete authentication transcripts.¶
Implementations SHOULD treat
server-pubkey and client-pubkey as identity-bearing
material and apply local authorization policy before accepting a
request.¶
Implementations need to account for generic Digest parsers that assume
username is always present. Implementations of this
specification MUST support the absence of
username for the algorithms defined here.¶
This mechanism prevents impersonation only when both sides have
securely provisioned peer public keys, bind those keys to the applicable
realm and authorization identity, and enforce the replay protections
required by this document. X25519 by itself is not authentication.
Authentication is achieved only by deriving a secret from a trusted peer
public key and proving possession of the corresponding private key through
the Digest response.¶
For X25519-HKDF-SHA256 and
X25519-HMAC-SHA256, the UAC trusts the UAS X25519 public key and
the UAS trusts the UAC X25519 public key. For
R25519-SCHNORR-SHA256, the UAS trusts the UAC ristretto255
public key, and the UAC trusts the UAS ristretto255 public key before
answering the challenge. The server-response parameter provides
authenticated server challenges when required by local policy.¶
The ristretto255 Schnorr algorithm authenticates the UAC by proving
knowledge of the private scalar corresponding to client-pubkey,
bound to the SIP Digest transcript. The server-response
parameter authenticates the server challenge by proving knowledge of the
private scalar corresponding to server-pubkey, bound to a
UAC-generated client-challenge.¶
Nonce freshness, nonce-count validation, client nonce validation, and replay-cache enforcement are part of the security of this mechanism. An implementation that accepts replayed Digest responses can authenticate a stale request even when the cryptographic proof or MAC is otherwise valid.¶
These algorithms authenticate SIP Digest exchanges and, when
qop=auth-int is used, provide integrity protection for the
authenticated SIP entity body. They do not establish a confidential
transport channel, protect SIP metadata, or provide media security.
Deployments requiring confidential signaling, SIP metadata protection,
transport-layer peer authentication, or media security
SHOULD use SIP over TLS and appropriate media-security
mechanisms.¶
Compromise of a provisioned private key enables impersonation for the identities and realms authorized for the corresponding public key. Deployments need operational procedures for protecting, rotating, and revoking keys according to local policy.¶
Schnorr nonces MUST be generated with high-quality randomness or by a deterministic nonce generation construction with equivalent security. Reusing a Schnorr nonce with the same private scalar can reveal the private scalar.¶
Implementations MUST use constant-time comparison when checking MAC or hash responses and SHOULD use constant-time scalar and group operations where provided by the cryptographic library.¶