{"_id":"@push.rocks/smartcrypto","_rev":"7-6c8dcfaa88cf48f77e17cb64b54f0289","name":"@push.rocks/smartcrypto","dist-tags":{"latest":"2.2.0"},"versions":{"2.0.1":{"name":"@push.rocks/smartcrypto","version":"2.0.1","author":{"name":"Lossless GmbH"},"license":"MIT","_id":"@push.rocks/smartcrypto@2.0.1","maintainers":[{"name":"lossless","email":"hello@lossless.com"}],"dist":{"shasum":"d598aab01b6a54759f3cc68dc44b338b4df07577","tarball":"https://registry.npmjs.org/@push.rocks/smartcrypto/-/smartcrypto-2.0.1.tgz","fileCount":25,"integrity":"sha512-FNfkaOgGP5j+tl6btmQ7TCcKvMHE+KFD+Upkg/dMR05A1ppOv6GgnWcmgy1U0IeNDv/mRtNzEeFsy7J0Mll97g==","signatures":[{"sig":"MEUCIQD1TTPe/Ko29hblekqDDgKGX0Gr1nbwUFMSh/53zVWNiQIgEtS0w3WxvUdyqStoLwxECWyM7SQRelBhOKd7Bvn2tGE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":18683},"main":"dist_ts/index.js","type":"module","private":false,"scripts":{"test":"(tstest test/ --web)","build":"(tsbuild --web)","buildDocs":"tsdoc"},"typings":"dist_ts/index.d.ts","_npmUser":{"name":"lossless","email":"hello@lossless.com"},"_npmVersion":"9.5.0","description":"easy crypto methods","directories":{},"_nodeVersion":"18.14.2","browserslist":["last 1 chrome versions"],"dependencies":{"node-forge":"^1.3.1","@types/node-forge":"^1.3.0","@pushrocks/smartpromise":"^3.1.3"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^18.11.4","@gitzone/tsrun":"^1.2.39","@gitzone/tstest":"^1.0.52","@gitzone/tsbuild":"^2.1.25","@pushrocks/tapbundle":"^5.0.4"},"_npmOperationalInternal":{"tmp":"tmp/smartcrypto_2.0.1_1689123160523_0.3728983472703338","host":"s3://npm-registry-packages"}},"2.0.2":{"name":"@push.rocks/smartcrypto","version":"2.0.2","author":{"name":"Lossless GmbH"},"license":"MIT","_id":"@push.rocks/smartcrypto@2.0.2","maintainers":[{"name":"lossless","email":"hello@lossless.com"}],"dist":{"shasum":"a43c48968da5c1e085a8b69bbf58882490945fbb","tarball":"https://registry.npmjs.org/@push.rocks/smartcrypto/-/smartcrypto-2.0.2.tgz","fileCount":25,"integrity":"sha512-CnhmRCHWz38kYBoIpJsNoMvCrcCMlTLaJ3Mfbx9V4LnzCLqgOSUYX3mERtANwUWeX3DdDNhBFn86oF+HwXaXkw==","signatures":[{"sig":"MEYCIQDDq0m/spTGnQDU+erScS8xjDi1XlWZda3xqXOqiyJMNQIhAPlBoO1uJyuzL35YAPYVXirIY947q2wRxJstr8SW1LWK","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":18382},"main":"dist_ts/index.js","type":"module","gitHead":"515257ff489ae66fe7a6b29eeb27b1f3c58ea924","private":false,"scripts":{"test":"(tstest test/ --web)","build":"(tsbuild --web)","buildDocs":"tsdoc"},"typings":"dist_ts/index.d.ts","_npmUser":{"name":"lossless","email":"hello@lossless.com"},"_npmVersion":"9.8.1","description":"easy crypto methods","directories":{},"_nodeVersion":"18.17.1","browserslist":["last 1 chrome versions"],"dependencies":{"node-forge":"^1.3.1","@types/node-forge":"^1.3.4","@push.rocks/smartpromise":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^20.5.1","@gitzone/tsrun":"^1.2.44","@gitzone/tstest":"^1.0.77","@gitzone/tsbuild":"^2.1.66","@push.rocks/tapbundle":"^5.0.15"},"_npmOperationalInternal":{"tmp":"tmp/smartcrypto_2.0.2_1692599605567_0.6418379075582328","host":"s3://npm-registry-packages"}},"2.0.5":{"name":"@push.rocks/smartcrypto","version":"2.0.5","author":{"name":"Lossless GmbH"},"license":"MIT","_id":"@push.rocks/smartcrypto@2.0.5","maintainers":[{"name":"lossless","email":"hello@lossless.com"}],"dist":{"shasum":"20485001d2cb98b81b5c6b99a5508975a239afb6","tarball":"https://registry.npmjs.org/@push.rocks/smartcrypto/-/smartcrypto-2.0.5.tgz","fileCount":25,"integrity":"sha512-FHK+ROfJtr50FrcJ78NdDBaWb9XrPdftDhoMC5OlLnWOOWvY1WAO/xpdmPztG5Ng9avuDO4M16gpi1c3JyT0QA==","signatures":[{"sig":"MEQCIGZllL/Ko7WkIXBzUSTXHIa4fcfgSMKzaEAy/qlNXZ7gAiBKqouEo7N8xS9VrmlrmgPS1aRV2AZZEj8F0xH5DBOD9Q==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":19217},"main":"dist_ts/index.js","type":"module","_from":"file:push.rocks-smartcrypto-2.0.5.tgz","private":false,"scripts":{"test":"(tstest test/ --web)","build":"(tsbuild --web)","buildDocs":"tsdoc"},"typings":"dist_ts/index.d.ts","_npmUser":{"name":"lossless","email":"hello@lossless.com"},"_resolved":"/tmp/7a4ae66e88ac2256efdd29575bc4b3aa/push.rocks-smartcrypto-2.0.5.tgz","_integrity":"sha512-FHK+ROfJtr50FrcJ78NdDBaWb9XrPdftDhoMC5OlLnWOOWvY1WAO/xpdmPztG5Ng9avuDO4M16gpi1c3JyT0QA==","_npmVersion":"10.2.3","description":"easy crypto methods","directories":{},"_nodeVersion":"21.2.0","browserslist":["last 1 chrome versions"],"dependencies":{"node-forge":"^1.3.1","@types/node-forge":"^1.3.11","@push.rocks/smartpromise":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^20.11.17","@git.zone/tsrun":"^1.2.46","@git.zone/tstest":"^1.0.86","@git.zone/tsbuild":"^2.1.72","@push.rocks/tapbundle":"^5.0.15"},"_npmOperationalInternal":{"tmp":"tmp/smartcrypto_2.0.5_1707497612828_0.8232168799689366","host":"s3://npm-registry-packages"}},"2.0.3":{"name":"@push.rocks/smartcrypto","version":"2.0.3","author":{"name":"Lossless GmbH"},"license":"MIT","_id":"@push.rocks/smartcrypto@2.0.3","maintainers":[{"name":"lossless","email":"hello@lossless.com"}],"dist":{"shasum":"95d9b660e8828932365e0a537277e1409c6e7388","tarball":"https://registry.npmjs.org/@push.rocks/smartcrypto/-/smartcrypto-2.0.3.tgz","fileCount":25,"integrity":"sha512-/8bmPB/9HmbkDODI/VOQmF4bkhNHliN4vJtOWXW6kbCF+YJpko66INFFHiwHpbsmrLoYp9L4tgr+u/5wnfI7DQ==","signatures":[{"sig":"MEYCIQC5V3oL1PWi57QwSZxoMs/J0txnhVbPXjfyDriQZUsrZQIhAMSx24HrTRPHxa8G1O3E4V4QOvNhPbVFG6dpC/b1TLnP","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":19218},"main":"dist_ts/index.js","type":"module","gitHead":"73df372f70513365cd5a163b12a7f534176f7dd4","private":false,"scripts":{"test":"(tstest test/ --web)","build":"(tsbuild --web)","buildDocs":"tsdoc"},"typings":"dist_ts/index.d.ts","_npmUser":{"name":"lossless","email":"hello@lossless.com"},"_npmVersion":"10.4.0","description":"easy crypto methods","directories":{},"_nodeVersion":"18.19.0","browserslist":["last 1 chrome versions"],"dependencies":{"node-forge":"^1.3.1","@types/node-forge":"^1.3.11","@push.rocks/smartpromise":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^20.11.17","@git.zone/tsrun":"^1.2.46","@git.zone/tstest":"^1.0.86","@git.zone/tsbuild":"^2.1.72","@push.rocks/tapbundle":"^5.0.15"},"_npmOperationalInternal":{"tmp":"tmp/smartcrypto_2.0.3_1707497792639_0.42542913025668105","host":"s3://npm-registry-packages"}},"2.0.4":{"name":"@push.rocks/smartcrypto","version":"2.0.4","author":{"name":"Lossless GmbH"},"license":"MIT","_id":"@push.rocks/smartcrypto@2.0.4","maintainers":[{"name":"lossless","email":"hello@lossless.com"}],"dist":{"shasum":"b55e1e3636cedabc9541431b77e6169fa7bc3902","tarball":"https://registry.npmjs.org/@push.rocks/smartcrypto/-/smartcrypto-2.0.4.tgz","fileCount":25,"integrity":"sha512-1+/5bsjyataf5uUkUNnnVXGRAt+gHVk1KDzozjTqgqJxHvQk1d9fVDohL6CxUhUucTPtu5VR5xNBiV8YCDuGyw==","signatures":[{"sig":"MEYCIQDy8Pg53Xw1O0Z6zz+OSBew4f/ay1W6bfeTI8TKS8h72QIhAMn4lJ199BrVRse0YZl2r0h8wlZFrQIRsjxe26yEpytm","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":19218},"main":"dist_ts/index.js","type":"module","gitHead":"316470fd97a4fc2588335fe4f61d3c5e2fe0e323","private":false,"scripts":{"test":"(tstest test/ --web)","build":"(tsbuild --web)","buildDocs":"tsdoc"},"typings":"dist_ts/index.d.ts","_npmUser":{"name":"lossless","email":"hello@lossless.com"},"_npmVersion":"10.4.0","description":"easy crypto methods","directories":{},"_nodeVersion":"18.19.0","browserslist":["last 1 chrome versions"],"dependencies":{"node-forge":"^1.3.1","@types/node-forge":"^1.3.11","@push.rocks/smartpromise":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^20.11.17","@git.zone/tsrun":"^1.2.46","@git.zone/tstest":"^1.0.86","@git.zone/tsbuild":"^2.1.72","@push.rocks/tapbundle":"^5.0.15"},"_npmOperationalInternal":{"tmp":"tmp/smartcrypto_2.0.4_1707497836917_0.33945487618555537","host":"s3://npm-registry-packages"}},"2.1.0":{"name":"@push.rocks/smartcrypto","version":"2.1.0","keywords":["cryptography","encryption","security","public key","private key","RSA","key pair generation","node-forge","typescript"],"author":"Lossless GmbH","license":"MIT","_id":"@push.rocks/smartcrypto@2.1.0","maintainers":[{"name":"lossless","email":"hello@lossless.com"}],"homepage":"https://code.foss.global/push.rocks/smartcrypto","dist":{"shasum":"52695acde963a8b90d2373dbbf5d28c05a19a7fd","tarball":"https://registry.npmjs.org/@push.rocks/smartcrypto/-/smartcrypto-2.1.0.tgz","fileCount":26,"integrity":"sha512-9Bi8Xam5oO1qCAfVTaaHX3tAdNvDNE78xhR5XrS+mPptWftbklOOg2/DGYSKeAJB1/yP5CzpiEQj4HNi8HR9tA==","signatures":[{"sig":"MEUCIQDVUCdfVcYBJ2N41S35o36I7kcwepzAbj6pnHPUKGRk4wIgaP4RMhZnWZ+4zq03LP5J0jU/1R8O1JQVRffYjdh5G9s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":39805},"main":"dist_ts/index.js","type":"module","private":false,"scripts":{"test":"(tstest test/ --web)","build":"(tsbuild --web)","buildDocs":"tsdoc"},"typings":"dist_ts/index.d.ts","_npmUser":{"name":"lossless","email":"hello@lossless.com"},"repository":{"url":"https://code.foss.global/push.rocks/smartcrypto.git","type":"git"},"description":"A library providing easy methods for cryptographic operations, including key pair generation.","directories":{},"_nodeVersion":"25.2.1","browserslist":["last 1 chrome versions"],"dependencies":{"node-forge":"^1.3.1","@types/node-forge":"^1.3.11","@push.rocks/smartpromise":"^4.0.3"},"_hasShrinkwrap":false,"devDependencies":{"@types/node":"^26.1.1","@git.zone/tsrun":"^2.0.5","@git.zone/tstest":"^3.6.6","@git.zone/tsbuild":"^4.4.2"},"_npmOperationalInternal":{"tmp":"tmp/smartcrypto_2.1.0_1784256514029_0.7758138532651204","host":"s3://npm-registry-packages-npm-production"}},"2.2.0":{"name":"@push.rocks/smartcrypto","version":"2.2.0","private":false,"description":"A library providing easy methods for cryptographic operations, including key pair generation.","main":"dist_ts/index.js","typings":"dist_ts/index.d.ts","author":"Task Venture Capital GmbH","license":"MIT","devDependencies":{"@git.zone/tsbuild":"^4.4.2","@git.zone/tsrun":"^2.0.6","@git.zone/tstest":"^3.6.7","@types/node":"^26.1.1"},"dependencies":{"@push.rocks/smartpromise":"^4.0.3","@types/node-forge":"^1.3.11","node-forge":"^1.3.1"},"browserslist":["last 1 chrome versions"],"type":"module","keywords":["cryptography","encryption","security","public key","private key","RSA","key pair generation","node-forge","typescript","WebCrypto","X25519","AES-GCM","HKDF"],"homepage":"https://code.foss.global/push.rocks/smartcrypto","repository":{"type":"git","url":"https://code.foss.global/push.rocks/smartcrypto.git"},"scripts":{"test":"(tstest test/ --web)","build":"(tsbuild --web)","buildDocs":"tsdoc"},"_nodeVersion":"25.2.1","_id":"@push.rocks/smartcrypto@2.2.0","dist":{"integrity":"sha512-Fnip8Fcx8QJsKWbjLtXZk3L3UlLJDmbpW+B2nJMw/npD3oK90BzCbkPBvJn/gMWYtNz3YvqQKTjT9LFZqQMHEA==","shasum":"87438cfbab5f76c5d75a1ac40fa46e249648373d","tarball":"https://registry.npmjs.org/@push.rocks/smartcrypto/-/smartcrypto-2.2.0.tgz","fileCount":38,"unpackedSize":139508,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDR3fIhaWh67X2MMxSeCkJN0OZTyS2GsJsg2HoN0wC8CAIhAISBPH0TC9uV7YoLZXBOvptBfOCAsQfaEQq31fTu8iFR"}]},"_npmUser":{"name":"lossless","email":"hello@lossless.com"},"directories":{},"maintainers":[{"name":"lossless","email":"hello@lossless.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/smartcrypto_2.2.0_1785431853669_0.18902803104856325"},"_hasShrinkwrap":false}},"time":{"created":"2023-07-12T00:52:40.403Z","modified":"2026-07-30T17:17:34.008Z","2.0.1":"2023-07-12T00:52:40.692Z","2.0.2":"2023-08-21T06:33:25.752Z","2.0.5":"2024-02-09T16:53:32.986Z","2.0.3":"2024-02-09T16:56:32.822Z","2.0.4":"2024-02-09T16:57:17.053Z","2.1.0":"2026-07-17T02:48:34.182Z","2.2.0":"2026-07-30T17:17:33.830Z"},"author":"Task Venture Capital GmbH","license":"MIT","homepage":"https://code.foss.global/push.rocks/smartcrypto","keywords":["cryptography","encryption","security","public key","private key","RSA","key pair generation","node-forge","typescript","WebCrypto","X25519","AES-GCM","HKDF"],"repository":{"type":"git","url":"https://code.foss.global/push.rocks/smartcrypto.git"},"description":"A library providing easy methods for cryptographic operations, including key pair generation.","maintainers":[{"name":"lossless","email":"hello@lossless.com"}],"readme":"# @push.rocks/smartcrypto\n\nCross-runtime cryptographic primitives for Node.js and browsers, including strict X25519 envelopes, AES-256-GCM authenticated encryption, DEK wrapping, and the existing RSA key APIs.\n\n## Issue Reporting and Security\n\nFor reporting bugs, issues, or security vulnerabilities, please visit [community.foss.global/](https://community.foss.global/). This is the central community hub for all issue reporting. Developers who sign and comply with our contribution agreement and go through identification can also get a [code.foss.global/](https://code.foss.global/) account to submit Pull Requests directly.\n\n## Install\n\n```bash\npnpm add @push.rocks/smartcrypto\n```\n\n## X25519 Envelope Profile\n\nThe fixed `x25519-hkdf-sha256-aes-256-gcm-v1` profile seals a `Uint8Array` to one recipient. It uses a fresh ephemeral X25519 key and random 12-byte AES-GCM nonce for every seal. The exact context bytes are mandatory AAD and are also bound into HKDF through their SHA-256 digest.\n\n```typescript\nimport {\n  generateX25519KeyPair,\n  openX25519Envelope,\n  sealX25519Envelope,\n} from '@push.rocks/smartcrypto';\n\nconst encoder = new TextEncoder();\nconst recipient = await generateX25519KeyPair();\nconst context = encoder.encode('tenant:example/secret:database-password');\n\nconst envelope = await sealX25519Envelope({\n  plaintext: encoder.encode('secret value'),\n  recipientPublicKey: recipient.publicKey,\n  recipientKeyId: 'recipient-key-2026-01',\n  context,\n});\n\nconst plaintext = await openX25519Envelope({\n  envelope,\n  recipientPrivateKey: recipient.privateKey,\n  expectedRecipientKeyId: 'recipient-key-2026-01',\n  context,\n});\n```\n\n`generateX25519KeyPair()` returns strict raw 32-byte public and private material. `importX25519PublicKey()`, `exportX25519PublicKey()`, `importX25519PrivateKey()`, and `exportX25519PrivateKey()` provide checked conversion to and from standard `CryptoKey` objects.\n\nThe envelope has exactly these fields:\n\n```typescript\ninterface IX25519EnvelopeV1 {\n  schemaVersion: 1;\n  profile: 'x25519-hkdf-sha256-aes-256-gcm-v1';\n  recipientKeyId: string;\n  ephemeralPublicKey: string;\n  nonce: string;\n  ciphertext: string;\n  tag: string;\n  contextDigest: string;\n}\n```\n\nAll binary envelope fields use canonical unpadded base64url. `parseX25519Envelope()` rejects extra fields, unknown versions and profiles, noncanonical encodings, incorrect fixed lengths, malformed key IDs, and ciphertexts larger than `SMARTCRYPTO_MAX_CIPHERTEXT_BYTES`.\n\n## AES-GCM And DEK Wrapping\n\n`aesGcmEncrypt()` and `aesGcmDecrypt()` accept only `Uint8Array` data and exact 32-byte AES keys. AAD is always required, although an explicitly supplied empty `Uint8Array` is valid. Encryption returns separate `nonce`, `ciphertext`, and 16-byte `tag` fields.\n\n```typescript\nimport {\n  aesGcmDecrypt,\n  aesGcmEncrypt,\n  generateDek,\n  generateAes256GcmKey,\n  rewrapDek,\n  unwrapDek,\n  wrapDek,\n} from '@push.rocks/smartcrypto';\n\nconst payloadAad = new TextEncoder().encode('payload binding');\nconst dek = generateDek();\nconst encryptedPayload = await aesGcmEncrypt({\n  key: dek,\n  plaintext: new TextEncoder().encode('payload'),\n  aad: payloadAad,\n});\n\nconst oldKek = generateAes256GcmKey();\nconst newKek = generateAes256GcmKey();\nconst oldWrapAad = new TextEncoder().encode('old KEK binding');\nconst newWrapAad = new TextEncoder().encode('new KEK binding');\nconst wrappedDek = await wrapDek({ dek, kek: oldKek, wrapAad: oldWrapAad });\n\nconst rewrappedDek = await rewrapDek({\n  wrappedDek,\n  currentKek: oldKek,\n  currentWrapAad: oldWrapAad,\n  newKek,\n  newWrapAad,\n});\n\nconst unwrappedDek = await unwrapDek({\n  wrappedDek: rewrappedDek,\n  kek: newKek,\n  wrapAad: newWrapAad,\n});\nconst plaintext = await aesGcmDecrypt({\n  key: unwrappedDek,\n  encryptedData: encryptedPayload,\n  aad: payloadAad,\n});\n```\n\n`rewrapDek()` only receives the wrapped DEK, so payload ciphertext, nonce, and tag remain unchanged during KEK rotation.\n\n## Errors\n\nCryptographic and validation failures use `SmartCryptoError` with a stable `TSmartCryptoErrorCode`. Messages, JSON output, Node inspection, stack metadata, and `cause` do not retain plaintext, keys, shared secrets, or ciphertext details.\n\n## RSA APIs\n\nThe existing `Smartcrypto`, `KeyPair`, `PrivateKey`, and `PublicKey` APIs remain available. RSA key generation and PEM conversion continue to use the existing behavior:\n\n```typescript\nimport { Smartcrypto } from '@push.rocks/smartcrypto';\n\nconst smartCrypto = new Smartcrypto();\nconst keyPair = await smartCrypto.createKeyPair();\nconst publicKeyPem = keyPair.publicKey.toPemString();\nconst privateKeyPem = keyPair.privateKey.toPemString();\n```\n\n`PublicKey.fromCanonicalRsaPublicPemString()` parses one canonical SPKI or PKCS#1 RSA public key with a modulus of at least 2048 bits. `PublicKey.verifyRs256()` verifies exact RSASSA-PKCS1-v1_5/SHA-256 signatures.\n\n## Runtime Support\n\nThe WebCrypto APIs are tested with Node.js 22 and current Chromium. Browsers require a secure context for WebCrypto.\n\n## License and Legal Information\n\nThis repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [license](license) file.\n\n**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.\n\n### Trademarks\n\nThis project is owned and maintained by Task Venture Capital GmbH. The names and logos associated with Task Venture Capital GmbH and any related products or services are trademarks of Task Venture Capital GmbH or third parties, and are not included within the scope of the MIT license granted herein.\n\nUse of these trademarks must comply with Task Venture Capital GmbH's Trademark Guidelines or the guidelines of the respective third-party owners, and any usage must be approved in writing. Third-party trademarks used herein are the property of their respective owners and used only in a descriptive manner, e.g. for an implementation of an API or similar.\n\n### Company Information\n\nTask Venture Capital GmbH<br>\nRegistered at District Court Bremen HRB 35230 HB, Germany\n\nFor any legal inquiries or further information, please contact us via email at hello@task.vc.\n\nBy using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.\n","readmeFilename":""}