Skip to content

Commit

Permalink
Update specification about signature and encyphering: ensure hash is …
Browse files Browse the repository at this point in the history
…being calculated from the plaintext document, and the signed document is encyphered
  • Loading branch information
Arkadiy Korotaev authored and monkeypants committed Apr 30, 2017
1 parent 089aa31 commit fb861c5
Showing 1 changed file with 72 additions and 38 deletions.
110 changes: 72 additions & 38 deletions docs/2.0/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ The `signature` part is created by a business system component trusted by the se

Receiving TAPs may also use the signature as a filter (messages with invalid signatures MAY be dropped by receiving TAPs, rather than delivered). This allows TAPs to buffer trusted components from anonymous denial of service attacks.

When a valid message is received, the TAP issues an HTTP 200 status and returns a response body with `Content-Type: application/json`, containing a HATEOS-style list of callback URLs.
When a valid message is received, the TAP issues an HTTP 200 status and returns a response body with `Content-Type: application/json`, containing received message information and optional HATEOS-style list of callback URLs.

```
{
Expand All @@ -144,9 +144,11 @@ See the TAP Protocol Details chapter for more information.

The TAP Protocol is a very simple REST API. One business sends a message directly to another business TAP endpoint (discovered via the DCP):

* The sender uses the HTTP POST verb (over HTTPS) to send the signed message to a TAP.
* The TAP replies with a HATEOS-style list of callback URLs.
* The TAP notarises some non-sensitive but useful data to the blockchain.
* The sender uses the HTTP POST verb (over HTTPS) to send the signed message to a TAP,
* The sender MUST use HTTPS,
* The TAP MUST reply with received message info or error response,
* The TAP MAY include a HATEOS-style list of callback URLs in the response,
* The TAP MAY notarize some non-sensitive but useful data.


## Sending a business message
Expand All @@ -162,12 +164,12 @@ Pre-requisites:

The process is:

* Sign the business message
* Create hash of signed business document
* Create hash of the business document
* Sign the business document
* Create cyphertext of the signed business document
* Create message
* Generate message signature
* POST message and signature to the recipient TAP
* Create message.json file
* Generate message.json signature
* POST message.json and signature to the recipient TAP


### Sign the Business Document
Expand All @@ -191,37 +193,64 @@ gpg2 \
--clearsign "doc.json"
```

Please see (TODO: examples) for more detailed explanation and real-world examples.


### Create hash of signed business document

The following hash algorithms are approved for use:

* SHA256
* SHA256 (default)
* SHA384
* SHA512
* BLAKE2b
* BLAKE2s

It is not necessary to sign the hash, because the entire message is signed.

This hash is of the cleartext "signed business document". When the recipient decrypts the business document, they are able to verify the hash. If the recipient-generated hash does not match the hash in the message, the recipient MUST NOT provide business acceptance of the document.
This hash is of the cleartext "business document" before the signing. When the recipient decrypts the business document, they are able to verify the hash. If the recipient-generated hash does not match the hash in the message, the recipient MUST NOT provide business acceptance of the document.

The hash is calculated before the signing, so, if sender for some reasons calculates 2 different signatures using 2 different keys - the hash is still the same.

**TODO: this is a very strange paragraph.**
If a 3rd party is presented with a copy of the message (including this hash), and with a copy of the signed business document, they are able to verify that the hash of the signed business document matches the hash in the message. That way, if the recipient provides business acceptance of the document, the third party knows the document that was accepted matches the cleartext document they were shown (despite the fact the 3rd party does not have access to recipient key material).

Assuming the current working directory contains a signed document `signed_doc.txt`, a hash of the signed document `signed_doc.hash` can be created with openssl like this:
Assuming the current working directory contains a document `doc.txt`, a hash of the signed document `doc.hash` can be created with openssl like this:

```bash
openssl dgst -sha256 -out "signed_doc.hash" "signed_doc.txt"
openssl dgst -sha256 -out "doc.hash" "doc.txt"
```

For example, if your doc.txt contains text `{"document_type": "invoice"}` (ending with newline character) the result is:
```
SHA256(doc.txt)= 14a62c86caa60bb3987248e93e51cacd46392562475738d3213b44f457ee163b
```
where `14a62c86caa60bb3987248e93e51cacd46392562475738d3213b44f457ee163b` is a document hash in plan SHA256 HEX format.


### Create cyphertext of signed business document

The message does not contain plaintext of the business message (signed or otherwise). It contains the hash of the signed plaintext (as per above), and cyphertext of the plaintext message.
The message does not contain plaintext of the business document (signed or otherwise). It contains the hash of the plaintext (as per above), and cyphertext of the signed plaintext document.

The cyphertext is created using public key cryptography, using the appropriate public key for the recipient business endpoint, and the appropriate private key of the sender. The public parts of these keypairs are discoverable using the appropriate DCP for each business identifier URNs, which is discoverable using the global DCL. Public keys MUST be published in ASCII-Armoured form in the DCP.
The cyphertext is created using public key cryptography, using the appropriate public key for the recipient business endpoint. The public parts of these keypairs are discoverable using the appropriate DCP for each business identifier URNs, which is discoverable using the global DCL. Public keys MUST be published in ASCII-Armoured form in the DCP.

Use of mature and extensively scrutinised cryptography implementations is strongly encouraged. The following examples use GnuPG, although any compliant RFC4880 implementation could be used in an equivalent way.
Example:

* Alice sends document to Bob
* Both Alice and Bob has public/private keypairs
* Both Alice and Bob published their public keys to the DCP
* Alice signs plaintext document by Alice's private key, having signed document as an output
* Alice encyphers signed document using Bob's public key, having encyphered value as a result
* Nobody except Bob can decypher the encyphered value (because only Bob owns his private keys)
...
* When message is received, Bob decyphers the encyphered value using his public key
* After that Bob validates the digital signature, using Alice's public key
* If everything went fine Bob can be sure that:

1. Only he decyphered the document
2. This document has been signed by Alice.

Use of mature, well-known and extensively scrutinised cryptography implementations is strongly encouraged. The following examples use GnuPG, although any compliant RFC4880 implementation could be used in an equivalent way.

Assuming the recipient's public key is not already in the sender's GnuPG keyring, but is in the current working directory as `recipient.gpg`, it can be added to the sender's GnuPG keyring like this:

Expand All @@ -234,6 +263,8 @@ With GnuPG, this is only necessary once. Subsequent messages to the same recipie

#### Note about published keys

Implementation-specific section.

Once the recipient's key has been added to the sender's keyring, and assuming the current working directory contains a signed document `signed_doc.txt`, and the user namespace identifier of the recipient public key is `91f68ffafa1288ad55cb3e61e937870fb5598cc098e125fe29412ab3047f15e1@dcp.testpoint.io` then cyphertext of signed business document can be created with:

```
Expand All @@ -246,8 +277,27 @@ gpg2 --armour \

This will create a file `cyphertext.gpg` in the current working directory, which has ASCII-Armour encoding (suitable for inclusion in a json document).

### Message format

Typical TAP message is:
```
{
"cyphertext": "string",
"hash": "string",
"sender": "string",
"reference": "string"
}
```

* "cyphertext" contains encrypted signed document
* encrypted by receiver public key
* signed by sender private key
* "hash" contains cryptographic hash of the document (before signing and encryption)
* "sender" contains unique participant identifier of client
* sender must make his public keys, used for signing operations, available in the DCP
* "reference" contains additional information about conversations or original message (which this one is replies to)

### Compose Message
### Compose Message Example

The `message` part is a mixture of cleartext metadata (used by TAPs) and enciphered payload (used by trusted business system components). The cleartext metadata does not contain sensitive business information, whereas access to the business-sensitive information within the payload is not necessary for participating in the TAP protocol.

Expand Down Expand Up @@ -295,41 +345,25 @@ if __name__ == "__main__":
compose_message()
```

### Message schema

```
{
"cyphertext": "string",
"hash": "string",
"sender": "string",
"reference": "string"
}
```

* "cyphertext" contains encrypted by GPG message using public key of receiver
* "hash" contains SHA256 hash of message (before encryption)
* "sender" contains unique participant identifier of client
* "reference" contains additional information

### Generate signature

The `signature` part is created by a business system component trusted by the sender (with access to the sender's private key material). The signature can also be used to uniquely identify the message contents.


Assuming the current working directory contains the message (as `message.json`), the following command will create a signature `message.sig`:

```bash
gpg2 --output message.sig --sign message.json
```

Implementation note: the easiest way to make sure that specific key is used for signature is to have only single private key in GPG keyring. GPG for linux support custom keyring location.


### Posting the message to the recipient TAP

Layered on top of HTTP Protocol:

* MUST use HTTPS (RFC2818).
* MUST use `Content-Type: multipart/form-data` (RFC2388)
* MUST NOT use `Content-Type: application/x-www-form-urlencode` (RFC1876 is NOT supported)
* MUST use only `Content-Type: multipart/form-data` (RFC2388)
* MAY explicitly declare `Content-Transfer-Encoding: base64`
* MUST NOT rely on additional TAP-related information in HTTP headers, such as message or conversation identifiers.

Expand All @@ -347,8 +381,8 @@ curl -X POST \

## Receipt and Technical Acknowledgement

When a valid message is received, the TAP issues an HTTP 200 status and returns a response body with `Content-Type: application/json`, containing a HATEOS-style list of callback URLs.
Check the [API](http://ausdigital.org/specs/ausdigital-tap/2.0/api) for possible error response.
When a valid message is received, the TAP issues an HTTP 200 status and returns a response body with `Content-Type: application/json`, containing information about the message and optional HATEOS-style list of callback URLs.
Check the [API](http://ausdigital.org/specs/ausdigital-tap/2.0/api) for possible responses, success and errors.

TODO:

Expand Down

0 comments on commit fb861c5

Please sign in to comment.