{"id":13403657,"url":"https://github.com/digitalbazaar/minimal-cipher","last_synced_at":"2025-05-05T18:29:21.998Z","repository":{"id":35045487,"uuid":"195124749","full_name":"digitalbazaar/minimal-cipher","owner":"digitalbazaar","description":"Minimal encryption/decryption JWE library, secure algs only, browser-compatible.","archived":false,"fork":false,"pushed_at":"2023-11-05T19:35:29.000Z","size":189,"stargazers_count":14,"open_issues_count":12,"forks_count":2,"subscribers_count":11,"default_branch":"main","last_synced_at":"2025-04-19T11:08:30.980Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/digitalbazaar.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-07-03T20:51:18.000Z","updated_at":"2023-11-29T00:14:31.000Z","dependencies_parsed_at":"2022-08-02T20:31:11.446Z","dependency_job_id":"cdd55109-1884-4855-b18f-3d6e568b9a53","html_url":"https://github.com/digitalbazaar/minimal-cipher","commit_stats":{"total_commits":202,"total_committers":7,"mean_commits":"28.857142857142858","dds":0.6237623762376238,"last_synced_commit":"198bbc82151339edb22e6ba608378bc1501de451"},"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fminimal-cipher","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fminimal-cipher/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fminimal-cipher/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/digitalbazaar%2Fminimal-cipher/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/digitalbazaar","download_url":"https://codeload.github.com/digitalbazaar/minimal-cipher/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252552694,"owners_count":21766747,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T19:01:32.920Z","updated_at":"2025-05-05T18:29:21.978Z","avatar_url":"https://github.com/digitalbazaar.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# Minimal Cipher _(@digitalbazaar/minimal-cipher)_\n\nMinimal encryption/decryption [JWE](https://tools.ietf.org/html/rfc7516)\nlibrary, secure algs only, browser-compatible.\n\n## Table of Contents\n\n- [Security](#security)\n- [Background](#background)\n- [Install](#install)\n- [Usage](#usage)\n- [Contribute](#contribute)\n- [Commercial Support](#commercial-support)\n- [License](#license)\n\n## Security\n\nTBD\n\n## Background\n\nEvery version of this library will only offer at most two algorithms\nfor encryption/decryption: a recommended algorithm and a FIPS-compliant\nalgorithm. The encryption API will expect the user to specify \"recommended\"\nor \"fips\" as the version of the algorithm to use, defaulting to \"recommended\".\n\nIn the event that the FIPS-compliant algorithm is the same as the recommended\none in a given version of this library, then that particular version will\nuse the same algorithm regardless of the user specified \"version\".\n\nThis version of the library will use \"XChaCha20-Poly1305\" as the \"recommended\"\nversion and 256-bit \"AES-GCM\" as the FIPS-compliant version.\n\nNote: XSalsa20-Poly1305 is an AE (Authenticated Encryption) algorithm, not\nan AEAD (Authenticated Encryption and Associated Data) algorithm, making it\nincompatible with the current requirements for a\n[JWE (JOSE Web Encryption)](https://tools.ietf.org/html/rfc7516)\n`protected` clear text header.\n\nThis library's API requires an interface for Key Encryption Key (KEKs). This\nenables key material that is protected from exfiltration to be used via HSM/SSM\nAPIs, including Web KMS (TODO: citation needed).\n\n## Install\n\n- Node.js 14+ required.\n- [Streams API][] required. Older browsers and Node.js \u003c18 must use a polyfill.\n- [Web Crypto API][] required. Older browsers and Node.js 14 must use a polyfill.\n\nTo install locally (for development):\n\n```\ngit clone https://github.com/digitalbazaar/minimal-cipher.git\ncd minimal-cipher\nnpm install\n```\n\n## Usage\n\nPick a Cipher interface (`recommended` or `fips`) and create an instance:\n\n```js\nimport {Cipher} from '@digitalbazaar/minimal-cipher';\n\nconst cipher = new Cipher(); // by default {version: 'recommended'}\n```\n\n### Encrypting\n\nTo encrypt something (to create a cipher, serialized as a JWE JSON document),\nyou will need:\n\n* Some data to encrypt (a string, an object, a stream)\n* Keys (called Key Agreement Keys, or KAKs for short)\n\n(You'll also need a `keyResolver`, more about that later.)\n\nFirst, assemble your Key Agreement public keys (you'll be encrypting with them,\nand the intended recipient will use the corresponding private keys to decrypt).\n\nPut together a list of `recipients` (essentially, you're listing the `id`s of\npublic/private key pairs that will be used to encrypt/decrypt the message):\n\n```js\n// Retrieve them from config, a ledger, registry or back channel\nconst keyAgreementKey = await fetchFromSomewhere();\n\n// or derive them from an existing Ed25519 signing key\nimport {X25519KeyAgreementKey2020} from '@digitalbazaar/x25519-key-agreement-key-2020';\nimport {Ed25519VerificationKey2020} from '@digitalbazaar/ed25519-verification-key-2020';\nconst keyPair = await Ed25519VerificationKey2020.generate();\n\nconst keyAgreementKey = X25519KeyPair.fromEd25519VerificationKey2020({keyPair});\n// If the source key pair didn't have a controller set, don't forget to set one:\nkeyAgreementKey.controller = did; // The controller's DID\nkeyAgreementKey.id = `${did}#${keyAgreementKey.fingerprint()}`;\n\n// or derive them from an authentication key extracted from DID Document\nconst didDoc = await veresDriver.get({did});\nconst authnKey = didDoc.getVerificationMethod({proofPurpose: 'authentication'});\nconst edKeyPair = await Ed25519VerificationKey2020.from(authnKey);\nconst keyPair = X25519KeyPair.fromEd25519VerificationKey2020({keyPair});\n\nconst recipient = {\n  header: {\n    kid: keyAgreementKey.id,\n    alg: 'ECDH-ES+A256KW'\n  }\n}\n\nconst recipients = [recipient];\n```\n\nYou'll also need a `keyResolver`. Notice that `recipients` lists only key IDs,\nnot the keys themselves. A `keyResolver` is a function that accepts a key ID\nand resolves to the public key corresponding to it.\n\nSome example resolvers:\n\n```js\n// Basic hardcoded key resolver; you already have the key material\nconst publicKeyNode = {\n  '@context': 'https://w3id.org/security/suites/x25519-2020/v1',\n  id: keyAgreementKey.id,\n  type: 'X25519KeyAgreementKey2020',\n  publicKeyMultibase: keyAgreementKey.publicKeyMultibase\n};\nconst keyResolver = async () =\u003e publicKeyNode;\n```\n\n```js\n// A more advanced resolver based on DID doc authentication keys\nconst keyResolver = async ({id}) =\u003e {\n  // Use veres driver to fetch the authn key directly\n  const keyPair = await Ed25519VerificationKey2020.from(await veresDriver.get({did: id}));\n  // Convert authn key to key agreement key\n  return X25519KeyPair.fromEd25519VerificationKey2020({keyPair});\n}\n```\n\n```js\n// Using did-veres-one driver as a resolver for did:v1:nym: DID keys\n// TODO: Implement this\n```\n\n```js\n// Using the did:key method driver as a key resolver\n```\n\nCreate the JWE:\n\n```js\n// To encrypt a string or a Uint8Array\nconst data = 'plain text';\nconst jweDoc = await cipher.encrypt({data, recipients, keyResolver});\n\n// To encrypt an object\nconst obj = {key: 'value'};\nconst jweDoc = await cipher.encryptObject({obj, recipients, keyResolver});\n```\n\n### Decrypting\n\nDecrypt a JWE JSON Document, using a private `keyAgreementKey`:\n\n```js\nconst data = await cipher.decrypt({jwe, keyAgreementKey});\n\nconst object = await cipher.decryptObject({jwe, keyAgreementKey});\n```\n\nTODO: Describe the required KEK API:\n// `id`, `algorithm`, `wrapKey({unwrappedKey})`, and `unwrapKey({wrappedKey})`\n\n## Contribute\n\nSee [the contribute file](https://github.com/digitalbazaar/bedrock/blob/master/CONTRIBUTING.md)!\n\nPRs accepted.\n\nIf editing the README, please conform to the\n[standard-readme](https://github.com/RichardLitt/standard-readme) specification.\n\n## Commercial Support\n\nCommercial support for this library is available upon request from\nDigital Bazaar: support@digitalbazaar.com\n\n## License\n\n[New BSD License (3-clause)](LICENSE) © Digital Bazaar\n\n[Streams API]: https://developer.mozilla.org/en-US/docs/Web/API/Streams_API\n[Web Crypto API]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalbazaar%2Fminimal-cipher","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdigitalbazaar%2Fminimal-cipher","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdigitalbazaar%2Fminimal-cipher/lists"}