-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 DRAFT VERSION 0.4.2 Oliver Vaughn Gould July 2010 PubKey Access Authentication Scheme, Version 1 ---------------------------------------------- 0 Introduction -------------- 0.1 Status of this Memo ------------------------ This document specifies a DRAFT protocol for the Internet community. 0.2 Copyright Notice --------------------- Copyright (C) Yahoo!, Inc. (2010). All rights reseved. 0.3 Abstract ------------- HTTP services are a core Internet technology, yet the Digest authentication scheme provided by RFC 2617 only describes authentication by way of shared-secrets (i.e. passwords). The PubKey Access Authentication scheme aims to enhance security on the World Wide Web by bringing an equivalent of SSH's "publickey" authentication method to challenge-based HTTP client authentication. 0.4 Table of Contents ---------------------- 1 PubKey Access Authentication Scheme, Version 1 1.1 Introduction 1.1.1 Purpose 1.1.2 Overall Operation 1.2 Specification of PubKey.v1 Headers 1.2.1 The WWW-Authenticate Response Header 1.2.2 The Authorize Request Header 1.3 Example 1.4 Proxy-Authentication and Proxy-Authorization 1.5 Operational Considerations 1.5.1 Replay Attacks 1.5.2 Man-in-the-Middle Attacks 1.5.3 Brute Force Attacks 1.5.4 Spoofing by Counterfeit Servers 2 References A Appendices A.1 Challenge Generation 1 PubKey Access Authentication Scheme, Version 1 ------------------------------------------------- 1.1 Introduction ----------------- 1.1.1 Purpose -------------- HTTP services are a core Internet technology, yet the Digest authentication scheme provided by RFC 2617 only describes authentication by way of shared-secrets (i.e. passwords). This model has operational drawbacks, as authenticating services are required to have access to a user's secret (or a hash thereof), or retrograde technologies, such as cookies, are employed. Similarly to SSH's "publickey" authentication method [RFC 4252], the PubKey Access Authentication scheme allows an HTTP server to authenticate clients using public key credentials. 1.1.2 Overall Operation ------------------------ Like the Digest Access Authentication Scheme [RFC 2617], the PubKey.v1 scheme is based on a simple challenge-response paradigm. The PubKey scheme responds to unauthorized clients with a challenge value; and a valid response contains a cryptographic signature of client's id, the authentication realm, and the server's challenge. The client's secret never leaves the client. The server verifies the client's signed authorization request with the client's published public keys. 1.2 Specification of PubKey.v1 Headers --------------------------------------- 1.2.1 The WWW-Authenticate Response Header ------------------------------------------- If a server receives a request for an access-protected object, and an acceptable Authorization header is not sent, the server responds with a "401 Unauthorized" status code, and a WWW-Authenticate header as per the framework defined above, which for the digest scheme is utilized as follows: challenge = "PubKey.v1" pubkey-challenge pubkey-challenge = 1#( realm | [domain] | challenge ) realm = "realm" "=" quoted-string domain = "domain" "=" <"> URI ( 1*SP URI ) <"> URI = absoluteURI | abs_path challenge = "challenge" "=" quoted-string The meanings of the values of the directives used above are as follows: realm A string to be displayed to clients so they know which username and public key to use. This string should contain at least the name of the host performing the authentication and might additionally indicate the collection of users who might have access. An example might be "admin@svc.domain.tld". domain An optional quoted, space-separated list of URIs that define the protection space. If a URI is an abs_path, it is relative to the canonical root URL of the server being accessed. An absoluteURI in this list may refer to a different server than the one being accessed. The client can use this list to determine the set of URIs for which the same authentication information may be sent: any URI that has a URI in this list as a prefix (after both have been made absolute) may be assumed to be in the same protection space. If this directive is omitted or its value is empty, the client should assume that the protection space consists of all URIs on the responding server. This directive is not meaningful in Proxy-Authenticate headers, for which the protection space is always the entire proxy; if present it should be ignored. challenge A quoted string of data, specified by the server, which should be returned by the client unchanged in the Authorization header of subsequent requests with URIs in the same protection space. It is recommended that this string be base 64 or hexadecimal data. 1.2.2 The Authorization Request Header ------------------------------------- The client is expected to retry the request, passing an Authorization header line, which is defined according to the framework above, utilized as follows. credentials = "PubKey.v1" privkey-credentials privkey-credentials = 1#( identifier | realm | challenge | signature ) identifier = "id" "=" identifier-value identifier-value = quoted-string challenge = "challenge" "=" challenge-value challenge-value = quoted-string signature = "signature" "=" signature-value signature-value = quoted-string The values of the challenge and realm fields must be those supplied in the WWW-Authenticate response header for the entity being requested. identifier The client identifier in the specified realm. I.e. the client's username. signature A quoted base 64 encoded string representation of a signature generated with the client's private key as follows. signature = BASE64( D^M( authorization )) authorization = identifier-value ";" realm-value ";" challenge-value If a directive or its value is improper, or required directives are missing, the proper response is 400 Bad Request. If the signature is invalid, then a login failure should be logged, since repeated login failures from a single client may indicate malfeasance. The client should be able to reuse this Authorization until a 401 Unauthorized is reached, or an Authentication-Info header provides a new challenge. 1.2.3 Authentication-Info Header --------------------------------- The optional Authentication-Info header may be used by the server to communicate some information regarding the successful authentication in the response. Specifically, this header can be used to send a new challenge to an authorized client. AuthenticationInfo = "Authentication-Info" ":" auth-info auth-info = 1#( next-challenge ) next-challenge = "challenge" "=" challenge-value The meanings of the values used above are as follows: next-challenge The following request on this domain should contain an authorization on this challenge value. It should be expected that reissuing the used Authorization header will result in a 401 Unauthorized response. 1.3 Example ------------ The following example assumes that an access-protected resource is being requested from the server via a GET request. The URI of the document is "http://svc.domain.tld/object". Both client and server know the public key for the user identified as "McFly" in the realm "users@svc.domain.tld". The first time the client requests the document, no Authorization header is sent, so the server responds with: 401 Unauthorized WWW-Authenticate: PubKey.v1 challenge="aKMpP2pkd3qiDnOUAHJ+pB1VdphaR2tFSF4J7wLWODk=;dXNlcnNAc3ZjLmRvbWFpbi50bGQ7MTI3ODExMjc5OTsxMjcuMC4wLjE7bThvK3JUa29rRVFPMFFLRUh2L280dz09", realm="users@svc.domain.tld" The client's user agent determines the client's identifier and private key to use for the realm. The user agent then uses this private key to sign the server's challenge, prompting the user as neccessary. Finally, the client sends a new request including the Authorization header: Authorization: PubKey.v1 id="McFly", challenge="aKMpP2pkd3qiDnOUAHJ+pB1VdphaR2tFSF4J7wLWODk=;dXNlcnNAc3ZjLmRvbWFpbi50bGQ7MTI3ODExMjc5OTsxMjcuMC4wLjE7bThvK3JUa29rRVFPMFFLRUh2L280dz09", realm="users@svc.domain.tld", signature="AAAAB3NzaC1yc2EAAAEAWARe6cScN5t0aFy0lBA1EbC/JoyRxsEuPsWtFZ3qw12lXYcmTXuq1v/0lwqcgZQgutQdiavR6O6157uyk0dkfuDXiuOjsngkmgp0oN/kwYxKPVrXMze1tFr8tFBUQU+JeCbvVd+o6LeD7pO29onXqf776N21nX1sRaeT+wX6qNMNEgJ7S3TzwTgMJ4Ub5dMCxXYCX7AW15YzLie213fvU3YiBh1ZHy//ubDb29d/2t941/gAdipjRQiabWK5lpfkmLJWJddlZq3IyFqiXMM1vpaGmiiM5w2fMpuzO8enyRTDtQQwLAxrffxY/n6RbGvUiEU4YzSGLlPE6KUU36dKOw==" The server verifies the client's signature on the following authorization string: McFly;users@svc.domain.tld;aKMpP2pkd3qiDnOUAHJ+pB1VdphaR2tFSF4J7wLWODk=;dXNlcnNAc3ZjLmRvbWFpbi50bGQ7MTI3ODExMjc5OTsxMjcuMC4wLjE7bThvK3JUa29rRVFPMFFLRUh2L280dz09 Assuming that the challenge generation algorithm described in section A.1 is used, the server then verfies its own signature of the challenge by decoding the challenge thusly: b64-server-signature = "aKMpP2pkd3qiDnOUAHJ+pB1VdphaR2tFSF4J7wLWODk=" b64-challenge = "dXNlcnNAc3ZjLmRvbWFpbi50bGQ7MTI3ODExMjc5OTsxMjcuMC4wLjE7bThvK3JUa29rRVFPMFFLRUh2L280dz09" challenge = "users@svc.domain.tld;1278112799;127.0.0.1;m8o+rTkokEQO0QKEHv/o4w==" After the server's signature is verified, it checks the realm, expiration, and source IP encoded in the challenge to authorize the request. 1.4 Proxy-Authentication and Proxy-Authorization ------------------------------------------------- The PubKey.v1 authentication scheme may also be used for authenticating clients to proxies, proxies to proxies, or proxies to origin servers by use of the Proxy-Authenticate and Proxy-Authorization headers. These headers are instances of the Proxy-Authenticate and Proxy-Authorization headers specified in sections 10.33 and 10.34 of the HTTP/1.1 specification [RFC 2616] and their behavior is subject to restrictions described there. The transactions for proxy authentication are very similar to those already described. Upon receiving a request which requires authentication, the proxy/server must issue the "407 Proxy Authentication Required" response with a "Proxy-Authenticate" header. The pubkey-challenge used in the Proxy-Authenticate header is the same as that for the WWW-Authenticate header as defined above in section 1.2.1. The client/proxy must then re-issue the request with a Proxy-Authorization header, with directives as specified for the Authorization header in section 1.2.2 above. Note that in principle a client could be asked to authenticate itself to both a proxy and an end-server, but never in the same response. 1.5 Operational Considerations ------------------------------- 1.5.1 Replay Attacks --------------------- The challenge generation scheme described in section A.1 includes a server-signed time, client IP address, and random seed; after verifying its own signature, the server verifies that the authorized request is from the expected source and within the allowed session time. The server may preempt the need for an expired transaction by sending a new challenge in an AuthorizationInfo header. 1.5.2 Man-in-the-Middle Attacks -------------------------------- In principal, it is not possible to distinguish untrusted intermediaries from trustworthy (e.g. HTTP or SOCKS) proxy servers. Therefore, the PubKey.v1 scheme does not attempt to implement any form of server authentication or endpoint confidentiality. A client's Authorization token may be stolen by intermediary servers. Some form of socket-or-application-layer cryptography should be utilized to establish confidentiality between endpoints. 1.5.3 Brute Force Attacks -------------------------- Brute force attacks against strong cryptographic keys (currently, RSA 2048 or stronger) are particularly ineffective, which is a major advantage of this authentication scheme over, for instance, the Digest scheme. The challenge generation algorithm described in section A.1 uses a secret value and digest algorithm to verify the returned, signed challenge. If an authorized attacker gains access to this value and determine the digest algorithm, it can override values encoded in the server's challenge. Note that such an attack can only be exploited by sending a manipulated challenge value with a valid signature from a client authorized to the given realm. The randomized seed value in the challenge helps to mitigate cryptanalytic attacks on the server's secret by introducing entropy into the signature. 1.5.4 Spoofing by Counterfeit Servers -------------------------------------- The PubKey.v1 authentication scheme does not provide any means for a client to validate a server. Some form of socket-or-application-layer cryptography should be utilized to establish confidentiality between endpoints. 2 References ------------ [RFC 2222] Simple Authentication and Security Layer (SASL) [RFC 2616] Hypertext Transfer Protocol -- HTTP/1.1 [RFC 2617] HTTP Authentication: Basic and Digest Access Authentication [RFC 2818] HTTP Over TLS [RFC 2743] Generic Security Service Application Program Interface Version 2, Update 1 [RFC 4251] The Secure Shell (SSH) Protocol Architecture [RFC 4252] The Secure Shell (SSH) Authentication Protocol Portions of this document were based directly on these references: Copyright (C) The Internet Society (1999, 2006). All Rights Reserved. A Appendices ------------- A.1 Challenge Generation ------------------------- - From a client's perspective, the challenge value is an opaque blob of data to be signed. However, the server can encode data into its challenge value in order to authenticate clients without maintaining state for all such requests. One possible challenge generation scheme is discussed below, but it can be replaced with no impact on the protocol. challenge-value = server-signature ";" encoded-challenge server-signature = BASE64( DIGEST( raw-server-signature ) ) raw-server-signature = raw-challenge ";" server-secret-value encoded-challenge = BASE64( raw-challenge ) raw-challenge = realm-value ";" ip-address ";" epoch-time ";" seed-value epoch-time = integer ip-address = seed-value = token [RFC 2616] server-secret-value = token [RFC 2616] The meanings of the values used above are as follows: DIGEST A digest algorithm such as SHA256. epoch-time The time at which the challenge was generated. The server may reference this field to determine whether the authorization has expired. ip-address The IP address of the client-side of the connection on which the request is being made. realm-value The realm-value specified in the WWW-Authenticate. seed-value A random value generated by the server to introduce entropy into the server's signatures. server-secret-value A secret value that only the server may access. This is used to 'sign' a challenge. The client's Authorization is validated by reconstructing the challenge with this secret. It would also be possible for a server to use a private key instead of a server-secret-value. Depending on the server's resources, it may be desirable to use a cipher algorithm instead of a digest algorithm. DRAFT VERSION 0.4.2 -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.14 (GNU/Linux) iEYEARECAAYFAkxJEZ0ACgkQkPEZLwKUCCVZeQCfb7zuztnPcEjCBF5CPtwaLJTd xrgAoJ4etR3erN/PstMEOJc1mjRR7OXr =R8Im -----END PGP SIGNATURE-----