decentralized-identity / DIDComm-js

JS implementation of pack and unpack
Apache License 2.0
55 stars 25 forks source link

Updating to JWE compliant data model #8

Open kdenhartog opened 5 years ago

kdenhartog commented 5 years ago

Recently there's been discussion to update this work to be fully JWE compliant. One of the proposed solutions that's come up is to generate the following format:

{
    "protected": base64url({
        "typ": "prs.hyperledger.aries-auth-message",
        "alg": "ECDH+XC20PKW",
        "enc":"XC20P"
    }),
    "recipients": [
        {
            "encrypted_key": "base64url(encrypted CEK)",
            "header": {
                "kid": "base58(Recipient vk)",
                "iv": "base64url(CEK encryption IV)",
                "pk": "compactJWE(Sender PK)"
            }
        },
        {
            "encrypted_key": "base64url(encrypted CEK)",
            "header": {
                "kid": "base58(Recipient vk)",
                "iv": "base64url(CEK encryption IV)",
                "pk": "compactJWE(Sender PK)"
            }
        }
    ],
    "aad": "base64url(sha256(concat('.',sort([recipients[0].kid, recipients[n].kid]))))",
    "iv": "base64url(content encryption IV)",
    "ciphertext": "base64url(ciphertext)",
    "tag": "base64url(AEAD Authentication Tag)"
}

Exploded example of compactJWE(Sender PK):
{
    "protected": base64url({
        "iv": "base64url(CEK encryption IV)",
        "epk": "Ephemeral JWK",
        "typ": "jose",
        "cty": "jwk+json",
        "alg": "ECDH-ES+XC20PKW",
        "enc":"XC20P"
    }),
    "encrypted_key": "base64url(encrypted CEK)",
    "iv": "base64url(content encryption IV)",
    "ciphertext": "base64url(Encrypted Sender vk as JWK)",
    "tag": "base64url(AEAD Authentication Tag)"
}

Here's a provided example of what this would look like:

{
    "protected": "eyJ0eXAiOiJwcnMuaHlwZXJsZWRnZXIuYXJpZXMtYXV0aC1tZXNzYWdlIiwiYWxnIjoiRUNESCtYQzIwUEtXIiwiZW5jIjoiWEMyMFAifQ",
    "recipients": [
        {
            "encrypted_key": "whpkJkvHRP0XX-EqxUOHhHIfuW8i5EMuR3Kxlg5NNIU",
            "header": {
                "kid": "5jMonJACEPcLfqVaz8jpqBLXHHKYgCE71XYBmFXhjZVX",
                "iv": "tjGLK6uChZatAyACFzGmFR4V9othKN8S",
                "tag": "ma9pIjkQuzaqvq_5y5vUlQ",
                "pk": "eyJpdiI6IldoVGptNi1DX2xiTlQ4Q2RzN2dfNjdMZzZKSEF3NU5BIiwiZXBrIjp7Imt0eSI6Ik9LUCIsImNydiI6IlgyNTUxOSIsIngiOiJnNjRfblJSSFQyYk1JX1hjT1dHRTdJOGdQcU1VWTF4aUNub2J0LVhDUkNZIn0sInR5cCI6Impvc2UiLCJjdHkiOiJqd2sranNvbiIsImFsZyI6IkVDREgtRVMrWEMyMFBLVyIsImVuYyI6IlhDMjBQIn0.4zUt5tOOlcQWskJqxfMi0tNsfUCAzb5_PDfPqQ1h0Vw.xYkeEXV1_cSYFEd6UBMIfl8MWQfHaDex.XSNKTRXye5-iSXQ-aS_vQVZNEgFE6iA9X_KgSRMzihQBMoI1j4WM3o-9dMT9TeSyMvdq3gXt1NpvLdZHpJplahhk3mxMZL-vawm5Prtf.H7a5N-dggwdesjHyJCl06w"
            }
        },
        {
            "encrypted_key": "dDHydlp_wlGt_zwR-yUvESx9fXuO-GRJFGtaw2u6CEw",
            "header": {
                "kid": "TfVVqzPT1FQHdq1CUDe9XYcg6Wu2QMusWKhGBXEZsosg",
                "iv": "7SFlGTxQ4Q2l02D9HRNdFeYQnwntyctb",
                "tag": "9-O6djpNAizix-ZnjAx-Fg",
                "pk": "eyJpdiI6IkV6UjBFaVRLazJCT19oc05qOVRxeU9PVmVLRFFPYVp1IiwiZXBrIjp7Imt0eSI6Ik9LUCIsImNydiI6IlgyNTUxOSIsIngiOiJoU1g1NGt5ZTdsd0pBdjlMaUplTmh4eFhaV1N0M3hLSDBXUmh6T1NOb1c0In0sInR5cCI6Impvc2UiLCJjdHkiOiJqd2sranNvbiIsImFsZyI6IkVDREgtRVMrWEMyMFBLVyIsImVuYyI6IlhDMjBQIn0.qKmU5xO8Z1ZtRBWEjEMixb5VZG0mrY0LnjUGjLqktwg.EG-VOZSC2vLdoO5l2_A37IYvdXCckLZp.D4kgD6bYL1YfXyApk5ESKE2sc8TUiO-QGBtY-M5hcV_F88JPZdsi53Qofxk02ZxPHJZK-abDy45pIMH6-KUMDfE6WKhW3nPQhydPYutv.0SO4VjM8sDH-wGHcEpinTg"
            }
        }
    ],
    "aad": "OGY5ZDIxMDE3YTQ4MTc4YWE5MTk0MWQyOGJmYjQ1ZmZmMTYzYTE3ZjUxYjc4YjA3YTlmY2FlMmMwOTFlMjBhZg",
    "ciphertext": "x1lnQq_pZLgU2ZC4",
    "tag": "2JgOe9SRjJXddT9TyIjqrg",
    "iv": "fDGEXswlWXOBx6FxPC_u6qIuhADnOrW1"
}

I'm curious what other's opinions are on this approach. I personally am not a fan of the bloat the compact JWE adds in order to encrypt the sender's public key. However, I've not found another approach yet that seems satisfactory. If anyone has some suggestions it would be appreciated.

@csuwildcat @awoie @christianlundkvist @dstrockis

kdenhartog commented 5 years ago

Please be aware, this issue is also posted on the Aries-RFC repo in Hyperledger. I'll facilitate communication across the groups if you don't want to track both conversations.

OR13 commented 5 years ago

Yes please, there needs to be a very clear encoding and signature documentation. I would say starting with JWE is a requirement for adoption of any sort.

Regarding bloat/size... its more important that the schema be well defined and support existing systems, like jose.

I suggest a well defined json schema be adopted as a first step, then you can get more compact representations for free later...

https://news.ycombinator.com/item?id=18189473

I don't see why we can't implement this entirely with did + jose and then add support for none jose crypto via case by case basis.

kdenhartog commented 5 years ago

Regarding bloat/size... its more important that the schema be well defined and support existing systems, like jose.

I'm looking into this now to make sure that the JWE header field pk is already defined. If it is then we'll be doing this. If it's not then we'll need to go down the path of registering the field in IANA at which point it make sense to define it in an optimised way.

I suggest a well defined json schema be adopted as a first step, then you can get more compact representations for free later...

As far as I'm aware, there's no other schema formats that are attempting to protect the sender's key. The additional bloat is coming from having to compact JWE encode a JWK in order to keep sender anonymity.

I don't see why we can't implement this entirely with did + jose and then add support for none jose crypto via case by case basis.

This is something I've been looking at so far. The tradeoffs to this is that it introduces a lot of confusing aspects for developers that leads to them shooting themselves in the foot. Here's a good blog post on the topic. This is one of the reasons that I've focused on being compliant with the JWE data model, but haven't been trying to build a compliant JWE library. It allows the implementation to be compatible (once everything get's registered) without all the downsides.

OR13 commented 4 years ago

Related work on edv using JWE as well... would be nice to sync all of this: https://github.com/digitalbazaar/encrypted-data-vaults/issues/5

dlongley commented 4 years ago

JFYI, we're using this library to generate JWEs with our edv work:

https://github.com/digitalbazaar/minimal-cipher

OR13 commented 4 years ago

Note the kid format...

keyAgreementKey.id = `${did}#${keyAgreementKey.fingerprint()}`;

I think we really need to get this id handling stuff into the did spec with some SHOULD language... I see this causing lots of interop issues if everyone is handling kid/id formats differently...

https://github.com/w3c/did-spec/issues/67