Blah blah
Opened this issue · 0 comments
The Web Resource Signature (WRS) Extension
Status of This Project
This specification along with the attached implementation was written to satisify the final project requirements for CS6161 Analysis of Algorithms, a course taught by Gabe Robins at the University of Virginia. The current implementation is expiremental in nature and should be treated as such. If you find this project intersting feel free to email me at nskelsey at gmail or open an issue on Github.
Abstract
This document speicifes version 0.1 of the WRS extension.
The WRS extension provides authentication of resources served over HTTP or HTTPS.
The extension lets a client and all future viewers of the session between a client and server verify the authenticity of data provided by the server during that session.
Contents
- Introduction
- URI Schemes
- The HTTP Transaction
- The Signature Algorithm
- Digital Commitments
- Limitations
- A Public Key Archcitecture
Introduction
The goal of the WRS extension is to create auditable resources served over the web. The extension specifies how an HTTP transaction is signed by a server and verified by a client. This form of authentication is different than the form provided TLS because it generates proofs that can be evaluated by third parties. The WRS extension therefore requires voluntary participation of servers and a seperate publicly known signature key for each server.
The extension uses digitial signatures to assert the intergrity and authenticity of a resource served to a potentially untrustworthy client. Claims of resources providing inaccurate data can be provably shown to be false. A signature generated over the resource behind a URL, creates a responsible party for that resource. If that resource were to ever be subtly changed or removed previously signed sessions could be used by a third party to prove that the resource changed.
It is too complicated to try and develop a public key infrastructe to distribute server public keys in this document. The problem of distributing these signature keys will be left as an open discussion in Section 8. However, given recent develops in distributed databases it may be possible to avoid the certificate authority system specified in rfc5208.
At its core, WRS is an extension to HTTP that works by manipulating headers. These headers along with the contents of an HTTP request-response pair forms the content of what a server will sign. This signature along with the entire transaction can then be stored for safe keeping and reverified by a client or a third party as needed. The exact format of the content that is signed is specified in Sections 2 and 3.
URI Schemes
In order to preserve compatability with http and promote the extensions use I am claiming (in an unofficial way of course) the URI Schemes httpv
and httpsv
to indicate a WRS extended resource served either by HTTP or HTTPS. WRS is backwards compatable with HTTP 1.1 meaning any server hosting httpv is implicitiy hosting resources over http. However, implentations can optionally enforce strict complicance with WRS 0.1 and drop http support.
As of this writing there is only one host on the internet serving either scheme. The endpoints are:
httpv://ahimsa.io:1070/api
httpsv://ahimsa.io:1075/api
However, since WRS is a backwards compataible extension both endpoints are still accessible via http and https respectively.
http://ahimsa.io:1070/api
https://ahimsa.io:1075/api
The server will still sign the http transaction, but most HTTP implementation will not record the entire transaction and thus the signature cannot be verified.
The HTTP Transaction
This extension only generates signed endpoints for transactions that only have one request and one response. The request to the server MUST be a GET
with an empty body. Supporting POST
requests may be useful in the future but it is unsupported as of now.
The servers response to that GET
is the canonical one. This is a response containing data produced by the server after processing the Request-URI. More details on the spefics can be found here.
Once the WRS enabled server processes the Request-URI then the server will proceed with signing the transaction only if processing the URI did not produce an error. The signature algorithm requires that the entire request and response be in memory and available before it can be completed.
The goal of using a single transaction is to produce a bundle of data from both the client's request and the server's response for the server to sign. This is done to ensure that the signature is tied to a particular URI accessed in the clients paramaterized way. The servers response is randomized to prevent an attacker from determistically controlling the input to the signature.
The HTTPV Request
The only difference between a httpv and an http request is the addition of one header. This header is Httpv-Ver: 0.1
and it should be included as the last header of the request. All other attributes are kept standard. A strict HTTPV server MUST respond with a 700 Bad Protocol
if that header is not present.
If an HTTPV server wishes to preserve backwards comptability it can ignore the header requirement and add it to the request object used in the signing bundle.
The HTTPV Response
The HTTPV response has several headers which must be present. Other than the addition of custom headers the response back to the client is standard HTTP.
Httpv-Ver: <string>
The version of WRS the server is running.
Httpv-Ts: <int>
This is the servers UNIX timestamp in seconds since 00:00 Jan 1 1970.
Httpv-N: <base64>
This is the servers nonce encoded as a base64. It is a 32 byte field.
Httpv-Sig: <base64>
This is the servers signature of the transaction. It is about 50 bytes.
The Transaction Bundle
When the server is ready to sign the entire transaction it must bundle the request and response together. For effecieny reasons the entire bundle is not signed, but instead the hash of the bundle is signed. This hash then sign process requires that the bundle computed by the client and the server be exactly identical.
This means that any sort of proxying that modifies the contents, or headers of the request or response will change the hash resulting in failed signature verification.
The bundle is arranged simply. The order is:
Request
Request Headers
Request Body
<lf>
Response
Response Headers
Response Body
It would make sense to define a formal structure for this bundle, but currently you should refer to the code for the exact layout.
The Signature Algorithm
With a bundle arranged, it must be hashed and then signed using an asymmetric key. Once generated the signature is converted to base64 and then added to the response headers as Httpv-Sig
. Note that the Httpv-Sig
header is the only datum left out of the transaction bundle.
Version 0.1 uses the sha256 hashing algorithm defined by NIST.
The Signature Algorithm is the Elipitic Curve Digital Signature Algorithm over the Koblitz curve secp256k1 defined in SEC2.
Signing
The signature is thus:
ecdsa_sign(secp256k1, privateKey, sha256(transaction_bundle))
Verifying
Verification is then:
ecdsa_verify(secp256k1, publicKey, sha256(transaction_bundle))
The signature is encoded and decoded from the response according to the Distinguished Encoding Rules (DER). This is a standardized format. More details live here.