Name: js-handler/node_modules/restify/node_modules/http-signature/http_signing.md 
1:
# Abstract
2:
 
3:
This document describes a way to add origin authentication, message integrity,
4:
and replay resistance to HTTP REST requests.  It is intended to be used over
5:
the HTTPS protocol.
6:
 
7:
# Copyright Notice
8:
 
9:
Copyright (c) 2011 Joyent, Inc. and the persons identified as document authors.
10:
All rights reserved.
11:
 
12:
Code Components extracted from this document must include MIT License text.
13:
 
14:
# Introduction
15:
 
16:
This protocol is intended to provide a standard way for clients to sign HTTP
17:
requests.  RFC2617 (HTTP Authentication) defines Basic and Digest authentication
18:
mechanisms, and RFC5246 (TLS 1.2) defines client-auth, both of which are widely
19:
employed on the Internet today.  However, it is common place that the burdens of
20:
PKI prevent web service operators from deploying that methodoloy, and so many
21:
fall back to Basic authentication, which has poor security characteristics.
22:
 
23:
Additionally, OAuth provides a fully-specified alternative for authorization
24:
of web service requests, but is not (always) ideal for machine to machine
25:
communication, as the key acquisition steps (generally) imply a fixed
26:
infrastructure that may not make sense to a service provider (e.g., symmetric
27:
keys).
28:
 
29:
Several web service providers have invented their own schemes for signing
30:
HTTP requests, but to date, none have been placed in the public domain as a
31:
standard.  This document serves that purpose.  There are no techniques in this
32:
proposal that are novel beyond previous art, however, this aims to be a simple
33:
mechanism for signing these requests.
34:
 
35:
# Signature Authentication Scheme
36:
 
37:
The "signature" authentication scheme is based on the model that the client must
38:
authenticate itself with a digital signature produced by either a private
39:
asymmetric key (e.g., RSA) or a shared symmetric key (e.g., HMAC).  The scheme
40:
is parameterized enough such that it is not bound to any particular key type or
41:
signing algorithm.  However, it does explicitly assume that clients can send an
42:
HTTP `Date` header.
43:
 
44:
## Authorization Header
45:
 
46:
The client is expected to send an Authorization header (as defined in RFC 2617)
47:
with the following parameterization:
48:
 
49:
    credentials := "Signature" params
50:
    params := 1#(keyId | algorithm | [headers] | [ext] | signature)
51:
    digitalSignature := plain-string
52:
 
53:
    keyId := "keyId" "=" <"> plain-string <">
54:
    algorithm := "algorithm" "=" <"> plain-string <">
55:
    headers := "headers" "=" <"> 1#headers-value <">
56:
    ext := "ext" "=" <"> plain-string <">
57:
    signature := "signature" "=" <"> plain-string <">
58:
 
59:
    headers-value := plain-string
60:
    plain-string   = 1*( %x20-21 / %x23-5B / %x5D-7E )
61:
 
62:
### Signature Parameters
63:
 
64:
#### keyId
65:
 
66:
REQUIRED.  The `keyId` field is an opaque string that the server can use to look
67:
up the component they need to validate the signature.  It could be an SSH key
68:
fingerprint, an LDAP DN, etc.  Management of keys and assignment of `keyId` is
69:
out of scope for this document.
70:
 
71:
#### algorithm
72:
 
73:
REQUIRED. The `algorithm` parameter is used if the client and server agree on a
74:
non-standard digital signature algorithm.  The full list of supported signature
75:
mechanisms is listed below.
76:
 
77:
#### headers
78:
 
79:
OPTIONAL.  The `headers` parameter is used to specify the list of HTTP headers
80:
used to sign the request.  If specified, it should be a quoted list of HTTP
81:
header names, separated by a single space character.  By default, only one
82:
HTTP header is signed, which is the `Date` header.  Note that the list MUST be
83:
specified in the order the values are concatenated together during signing. To
84:
include the HTTP request line in the signature calculation, use the special
85:
`request-line` value.  While this is overloading the definition of `headers` in
86:
HTTP linguism, the request-line is defined in RFC 2616, and as the outlier from
87:
headers in useful signature calculation, it is deemed simpler to simply use
88:
`request-line` than to add a separate parameter for it.
89:
 
90:
#### extensions
91:
 
92:
OPTIONAL.  The `extensions` parameter is used to include additional information
93:
which is covered by the request.  The content and format of the string is out of
94:
scope for this document, and expected to be specified by implementors.
95:
 
96:
#### signature
97:
 
98:
REQUIRED.  The `signature` parameter is a `Base64` encoded digital signature
99:
generated by the client. The client uses the `algorithm` and `headers` request
100:
parameters to form a canonicalized `signing string`.  This `signing string` is
101:
then signed with the key associated with `keyId` and the algorithm
102:
corresponding to `algorithm`.  The `signature` parameter is then set to the
103:
`Base64` encoding of the signature.
104:
 
105:
### Signing String Composition
106:
 
107:
In order to generate the string that is signed with a key, the client MUST take
108:
the values of each HTTP header specified by `headers` in the order they appear.
109:
 
110:
1. If the header name is not `request-line` then append the lowercased header
111:
   name followed with an ASCII colon `:` and an ASCII space ` `.
112:
2. If the header name is `request-line` then appened the HTTP request line,
113:
   otherwise append the header value.
114:
3. If value is not the last value then append an ASCII newline `\n`. The string
115:
   MUST NOT include a trailing ASCII newline.
116:
 
117:
# Example Requests
118:
 
119:
All requests refer to the following request (body ommitted):
120:
 
121:
    POST /foo HTTP/1.1
122:
    Host: example.org
123:
    Date: Tue, 07 Jun 2011 20:51:35 GMT
124:
    Content-Type: application/json
125:
    Content-MD5: h0auK8hnYJKmHTLhKtMTkQ==
126:
    Content-Length: 123
127:
 
128:
The "rsa-key-1" keyId refers to a private key known to the client and a public
129:
key known to the server. The "hmac-key-1" keyId refers to key known to the
130:
client and server.
131:
 
132:
## Default parameterization
133:
 
134:
The authorization header and signature would be generated as:
135:
 
136:
    Authorization: Signature keyId="rsa-key-1",algorithm="rsa-sha256",signature="Base64(RSA-SHA256(signing string))"
137:
 
138:
The client would compose the signing string as:
139:
 
140:
    date: Tue, 07 Jun 2011 20:51:35 GMT
141:
 
142:
## Header List
143:
 
144:
The authorization header and signature would be generated as:
145:
 
146:
    Authorization: Signature keyId="rsa-key-1",algorithm="rsa-sha256",headers="request-line date content-type content-md5",signature="Base64(RSA-SHA256(signing string))"
147:
 
148:
The client would compose the signing string as (`+ "\n"` inserted for
149:
readability):
150:
 
151:
    POST /foo HTTP/1.1 + "\n"
152:
    date: Tue, 07 Jun 2011 20:51:35 GMT + "\n"
153:
    content-type: application/json + "\n"
154:
    content-md5: h0auK8hnYJKmHTLhKtMTkQ==
155:
 
156:
## Algorithm
157:
 
158:
The authorization header and signature would be generated as:
159:
 
160:
    Authorization: Signature keyId="hmac-key-1",algorithm="hmac-sha1",signature="Base64(HMAC-SHA1(signing string))"
161:
 
162:
The client would compose the signing string as:
163:
 
164:
    date: Tue, 07 Jun 2011 20:51:35 GMT
165:
 
166:
# Signing Algorithms
167:
 
168:
Currently supported algorithm names are:
169:
 
170:
* rsa-sha1
171:
* rsa-sha256
172:
* rsa-sha512
173:
* dsa-sha1
174:
* hmac-sha1
175:
* hmac-sha256
176:
* hmac-sha512
177:
 
178:
# Security Considerations
179:
 
180:
## Default Parameters
181:
 
182:
Note the default parameterization of the `Signature` scheme is only safe if all
183:
requests are carried over a secure transport (i.e., TLS).  Sending the default
184:
scheme over a non-secure transport will leave the request vulnerable to
185:
spoofing, tampering, replay/repudiaton, and integrity violations (if using the
186:
STRIDE threat-modeling methodology).
187:
 
188:
## Insecure Transports
189:
 
190:
If sending the request over plain HTTP, service providers SHOULD require clients
191:
to sign ALL HTTP headers, and the `request-line`.  Additionally, service
192:
providers SHOULD require `Content-MD5` calculations to be performed to ensure
193:
against any tampering from clients.
194:
 
195:
## Nonces
196:
 
197:
Nonces are out of scope for this document simply because many service providers
198:
fail to implement them correctly, or do not adopt security specfiications
199:
because of the infrastructure complexity.  Given the `header` parameterization,
200:
a service provider is fully enabled to add nonce semantics into this scheme by
201:
using something like an `x-request-nonce` header, and ensuring it is signed
202:
with the `Date` header.
203:
 
204:
## Clock Skew
205:
 
206:
As the default scheme is to sign the `Date` header, service providers SHOULD
207:
protect against logged replay attacks by enforcing a clock skew.  The server
208:
SHOULD be synchronized with NTP, and the recommendation in this specification
209:
is to allow 300s of clock skew (in either direction).
210:
 
211:
## Required Headers to Sign
212:
 
213:
It is out of scope for this document to dictate what headers a service provider
214:
will want to enforce, but service providers SHOULD at minimum include the
215:
`Date` header.
216:
 
217:
# References
218:
 
219:
## Normative References
220:
 
221:
* [RFC2616] Hypertext Transfer Protocol -- HTTP/1.1
222:
* [RFC2617] HTTP Authentication: Basic and Digest Access Authentication
223:
* [RFC5246] The Transport Layer Security (TLS) Protocol Version 1.2
224:
 
225:
## Informative References
226:
 
227:
    Name: Mark Cavage (editor)
228:
    Company: Joyent, Inc.
229:
    Email: [email protected]
230:
    URI: http://www.joyent.com
231:
 
232:
# Appendix A - Test Values
233:
 
234:
The following test data uses the RSA (2048b) keys, which we will refer
235:
to as `keyId=Test` in the following samples:
236:
 
237:
   -----BEGIN PUBLIC KEY-----
238:
   MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDCFENGw33yGihy92pDjZQhl0C3
239:
   6rPJj+CvfSC8+q28hxA161QFNUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6
240:
   Z4UMR7EOcpfdUE9Hf3m/hs+FUR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJw
241:
   oYi+1hqp1fIekaxsyQIDAQAB
242:
   -----END PUBLIC KEY-----
243:
 
244:
    -----BEGIN RSA PRIVATE KEY-----
245:
    MIICXgIBAAKBgQDCFENGw33yGihy92pDjZQhl0C36rPJj+CvfSC8+q28hxA161QF
246:
    NUd13wuCTUcq0Qd2qsBe/2hFyc2DCJJg0h1L78+6Z4UMR7EOcpfdUE9Hf3m/hs+F
247:
    UR45uBJeDK1HSFHD8bHKD6kv8FPGfJTotc+2xjJwoYi+1hqp1fIekaxsyQIDAQAB
248:
    AoGBAJR8ZkCUvx5kzv+utdl7T5MnordT1TvoXXJGXK7ZZ+UuvMNUCdN2QPc4sBiA
249:
    QWvLw1cSKt5DsKZ8UETpYPy8pPYnnDEz2dDYiaew9+xEpubyeW2oH4Zx71wqBtOK
250:
    kqwrXa/pzdpiucRRjk6vE6YY7EBBs/g7uanVpGibOVAEsqH1AkEA7DkjVH28WDUg
251:
    f1nqvfn2Kj6CT7nIcE3jGJsZZ7zlZmBmHFDONMLUrXR/Zm3pR5m0tCmBqa5RK95u
252:
    412jt1dPIwJBANJT3v8pnkth48bQo/fKel6uEYyboRtA5/uHuHkZ6FQF7OUkGogc
253:
    mSJluOdc5t6hI1VsLn0QZEjQZMEOWr+wKSMCQQCC4kXJEsHAve77oP6HtG/IiEn7
254:
    kpyUXRNvFsDE0czpJJBvL/aRFUJxuRK91jhjC68sA7NsKMGg5OXb5I5Jj36xAkEA
255:
    gIT7aFOYBFwGgQAQkWNKLvySgKbAZRTeLBacpHMuQdl1DfdntvAyqpAZ0lY0RKmW
256:
    G6aFKaqQfOXKCyWoUiVknQJAXrlgySFci/2ueKlIE1QqIiLSZ8V8OlpFLRnb1pzI
257:
    7U1yQXnTAEFYM560yJlzUpOb1V4cScGd365tiSMvxLOvTA==
258:
    -----END RSA PRIVATE KEY-----
259:
 
260:
And all examples use this request:
261:
 
262:
    POST /foo?param=value&pet=dog HTTP/1.1
263:
    Host: example.com
264:
    Date: Thu, 05 Jan 2012 21:31:40 GMT
265:
    Content-Type: application/json
266:
    Content-MD5: Sd/dVLAcvNLSq16eXua5uQ==
267:
    Content-Length: 18
268:
 
269:
    {"hello": "world"}
270:
 
271:
### Default
272:
 
273:
The string to sign would be:
274:
 
275:
    date: Thu, 05 Jan 2012 21:31:40 GMT
276:
 
277:
The Authorization header would be:
278:
 
279:
    Authorization: Signature keyId="Test",algorithm="rsa-sha256",signature="JldXnt8W9t643M2Sce10gqCh/+E7QIYLiI+bSjnFBGCti7s+mPPvOjVb72sbd1FjeOUwPTDpKbrQQORrm+xBYfAwCxF3LBSSzORvyJ5nRFCFxfJ3nlQD6Kdxhw8wrVZX5nSem4A/W3C8qH5uhFTRwF4ruRjh+ENHWuovPgO/HGQ="
280:
 
281:
### All Headers
282:
 
283:
Parameterized to include all headers, the string to sign would be (`+ "\n"`
284:
inserted for readability):
285:
 
286:
    POST /foo?param=value&pet=dog HTTP/1.1 + "\n"
287:
    host: example.com + "\n"
288:
    date: Thu, 05 Jan 2012 21:31:40 GMT + "\n"
289:
    content-type: application/json + "\n"
290:
    content-md5: Sd/dVLAcvNLSq16eXua5uQ== + "\n"
291:
    content-length: 18
292:
 
293:
The Authorization header would be:
294:
 
295:
    Authorization: Signature keyId="Test",algorithm="rsa-sha256",headers="request-line host date content-type content-md5 content-length",signature="Gm7W/r+e90REDpWytALMrft4MqZxCmslOTOvwJX17ViEBA5E65QqvWI0vIH3l/vSsGiaMVmuUgzYsJLYMLcm5dGrv1+a+0fCoUdVKPZWHyImQEqpLkopVwqEH67LVECFBqFTAKlQgBn676zrfXQbb+b/VebAsNUtvQMe6cTjnDY="