Code Monkey home page Code Monkey logo

didcomm-js's Introduction

Archived

This implementation hasn't been actively maintained for quite some time. If you'd like to utilize a current implementation of DIDCommV1 which is actively tracking the AIP1.0 and AIP2.0 standards checkout aries-framework-javascript. If you're looking for DIDCommV2 based implementations check out the implementations listed here.

DIDCommV1-crypto-js

Javascript (written in typescript) version of the cryptographic envelope of DIDComm. This library is built for any javascript environment that needs to . It is built on libsodium-js and follows the specs documented in the docs folder.

installation

This package is currently not available on NPM: It will be added to npm under the package name DIDComm-crypto-js when a CI/CD platform can be added to publish it.

Usage

NOTE THESE APIs are currently unstable at this point to account for new non-repudiable signing changes

There's currently 4 APIs of use in this library that will handle encryption and decryption to multiple recipients. Messages encrypted with this library support repudiable authentication and anonymous encryption. There's additional APIs to support non-repudiable signing and verification of messages.

Encrypt with repudiable authentication

pack_auth_msg_for_recipients(message, recipientKeyList, senderKeyPair, nonRepudiable = false) should be the default method used. This example shows how to use repudiable authentication to pack a message for the recipient.

    const didcomm = new DIDComm()
    await didcomm.Ready
    const alice = await didcomm.generateKeyPair()
    const bob = await didcomm.generateKeyPair()
    const message = 'I AM A PRIVATE MESSAGE'
    const packedMsg = await didcomm.pack_auth_msg_for_recipients(message, [bob.publicKey], alice)
    const unpackedMsg = await didcomm.unpackMessage(packedMsg, bob)

Encrypt with non-repudiable authentication

To Encrypt a message for a recipient and sign the message using a non-repudiable signature change the nonRepudiable variable should be set to true. To understand what non-repudiation is and when it should be used refer here.

    const didcomm = new DIDComm()
    await didcomm.Ready
    const alice = await didcomm.generateKeyPair()
    const bob = await didcomm.generateKeyPair()
    const message = 'I AM A PRIVATE MESSAGE'
    const packedMsg = await didcomm.pack_auth_msg_for_recipients(message, [bob.publicKey], alice, true)
    const unpackedMsg = await didcomm.unpackMessage(packedMsg, bob)

Encrypt with no authentication

For privacy reasons or to meet the principle of least information, it may be necessary to encrypt a message, but does not provide authentication guarantees.

    const didcomm = new DIDComm()
    await didcomm.Ready
    const bob = await didcomm.generateKeyPair()
    const message = JSON.stringify({
        "@type": "did:example:1234567890;spec/test",
        data: "I AM A SIGNED MESSAGE"
    })
    const packedMsg = await didcomm.pack_anon_msg_for_recipients(message, [bob.publicKey])
    const unpackedMsg = await didcomm.unpackMessage(packedMsg, bob)

Non-repudiable signature with no encryption

In very specific use cases like the invitation protocol or incredibly short lived connection (1 round trip only) it's necessary to provide data in a plaintext format to provide a key. In these cases we will sign the data, but leave it unencrypted.

    const didcomm = new DIDComm()
    await didcomm.Ready
    const bob = await didcomm.generateKeyPair()
    const message = "I AM A PUBLIC MESSAGE"
    const packedMsg = await didcomm.pack_nonrepudiable_msg_for_anyone(message, bob)
    const unpackedMsg = await didcomm.unpackMessage(packedMsg, bob)

Authentication notes

To perform authentication this library should be combined with resolution of a DID Document to ensure the key used by the sender is contained in a valid DID Document. This funcationality is considered out of scope for this library.

didcomm-js's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

didcomm-js's Issues

Add example strings to readme

Would be nice to include encoded / non encoded examples, so that users know what the end result is.

Using JOSE under the hood, is a huge plus, it should be highlighted in the readme.

How to construct valid messages according to a protocol version?

The readme shows:

  const message = JSON.stringify({
        "@type": "did:example:1234567890;spec/test",
        data: "I AM A SIGNED MESSAGE"
    })

I would expect this library to assist implementers in crafting messages that are formatted correctly, in addition to packing / unpacking.

The code used to construct a valid message, is undoubtably in other repo, can establish a clearer understanding of the message format this library should be used with?

Should the crypto layer support "profiles" for crypto?

In TLS 1.3 as well as other similar data models like paseto there's been moves to make crypto options more rigid to prevent "negotiation hell" which allows for potential insecurities.

I'd like to see us do something similar if we're going to expand the crypto primitives used:

For example, one suite would use: XChacha20Poly1305 with x25519/ed25519 keys
Another would use: AES-GCM with ES256K keys
And a final option would be: AES-GCM with P-256 keys to support cryptographic enclaves.

I'd also like to see us standardize on an encoding scheme to make implementation easier. If we can't choose one than I'd like to see us support a standard way to support multiple encodings.

Where do others fall in regards to this thinking?

Updating to JWE compliant data model

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

Consistent Variable naming

Right now in some cases variables use camel case and some use snake case. This library should support a consistent pattern and stick to it.

OpenPGP Support

@kdenhartog we talked about this ages ago, but it came up on the aries call:

https://github.com/decentralized-identity/github-did/blob/master/packages/lib/src/v2/__fixtures__/encryptedMessageFor.json

I recently added Universal Resolver and Yubikey support to:

https://github.com/transmute-industries/PROPOSAL-OpenPgpSignature2019

Since PGP / JOSE / JSON-LD are all not formally related, I wanted to kickoff the converation around OpenPGP support for DIDComm.

There are lots for legacy systems and hardware which use PGP. It would be cool to establish a pattern of use for PGP and DIDComm.

Comparison to UMF (Universal Messaging Format)

https://github.com/cjus/umf/blob/master/umf.md

Seems like these things are similar, or rather that DIDComm is used to construct messages that are likely to be of similar format. At the very least, its worth listing similar concepts.

The main reason I link this is the clarity over HTTP vs Peer 2 Peer.

I think that kind of definition is probably buried elsewhere in hyperledger, and it should be highlighted more.

Related HN Article: https://news.ycombinator.com/item?id=17302596

Separate pack_auth_msg?

I'm confused by the separate pack_auth_msg method included in the library. What is the purpose of having it separated from packMessage? It would be good to have clearer documentation on the reasoning.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.