kush-e2e 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -0
- package/dist/index.d.mts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +82 -0
- package/dist/index.mjs +47 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# KushE2E
|
|
2
|
+
|
|
3
|
+
End-to-end encryption library for secure peer-to-peer communication using ECDH key exchange and AES-256 encryption.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install kush-e2e
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
import { KushE2E } from 'kush-e2e';
|
|
15
|
+
|
|
16
|
+
// Create identities
|
|
17
|
+
const identity1 = await KushE2E.createIdentity();
|
|
18
|
+
const identity2 = await KushE2E.createIdentity();
|
|
19
|
+
|
|
20
|
+
// Derive shared session key
|
|
21
|
+
const sessionKey = await KushE2E.deriveSessionKey(
|
|
22
|
+
identity1.privateKey,
|
|
23
|
+
identity2.publicKey
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
// Encrypt message
|
|
27
|
+
const encrypted = await KushE2E.encrypt('Hello World', sessionKey);
|
|
28
|
+
|
|
29
|
+
// Decrypt message
|
|
30
|
+
const decrypted = await KushE2E.decrypt(encrypted, sessionKey);
|
|
31
|
+
console.log(decrypted); // "Hello World"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Features
|
|
35
|
+
|
|
36
|
+
- ECDH-ES+A256KW key exchange with P-256 curve
|
|
37
|
+
- AES-256 GCM encryption/decryption
|
|
38
|
+
- Cross-platform crypto support (Node.js and browsers)
|
|
39
|
+
- Full TypeScript support
|
|
40
|
+
|
|
41
|
+
## License
|
|
42
|
+
|
|
43
|
+
ISC
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface Identity {
|
|
2
|
+
publicKey: string;
|
|
3
|
+
privateKey: string;
|
|
4
|
+
}
|
|
5
|
+
declare class KushE2E {
|
|
6
|
+
static createIdentity(): Promise<Identity>;
|
|
7
|
+
static deriveSessionKey(myPrivateKeyPem: string, theirPublicKeyPem: string): Promise<string>;
|
|
8
|
+
static encrypt(text: string, sessionKey: string): Promise<string>;
|
|
9
|
+
static decrypt(cipherText: string, sessionKey: string): Promise<string>;
|
|
10
|
+
private static _stringToKey;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { type Identity, KushE2E };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
interface Identity {
|
|
2
|
+
publicKey: string;
|
|
3
|
+
privateKey: string;
|
|
4
|
+
}
|
|
5
|
+
declare class KushE2E {
|
|
6
|
+
static createIdentity(): Promise<Identity>;
|
|
7
|
+
static deriveSessionKey(myPrivateKeyPem: string, theirPublicKeyPem: string): Promise<string>;
|
|
8
|
+
static encrypt(text: string, sessionKey: string): Promise<string>;
|
|
9
|
+
static decrypt(cipherText: string, sessionKey: string): Promise<string>;
|
|
10
|
+
private static _stringToKey;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { type Identity, KushE2E };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
KushE2E: () => KushE2E
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
var jose = __toESM(require("jose"));
|
|
37
|
+
var KushE2E = class {
|
|
38
|
+
static async createIdentity() {
|
|
39
|
+
const { publicKey, privateKey } = await jose.generateKeyPair("ECDH-ES+A256KW", {
|
|
40
|
+
crv: "P-256",
|
|
41
|
+
extractable: true
|
|
42
|
+
});
|
|
43
|
+
return {
|
|
44
|
+
publicKey: await jose.exportSPKI(publicKey),
|
|
45
|
+
privateKey: await jose.exportPKCS8(privateKey)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
static async deriveSessionKey(myPrivateKeyPem, theirPublicKeyPem) {
|
|
49
|
+
const myPriv = await jose.importPKCS8(myPrivateKeyPem, "ECDH-ES+A256KW");
|
|
50
|
+
const theirPub = await jose.importSPKI(theirPublicKeyPem, "ECDH-ES+A256KW");
|
|
51
|
+
const crypto = globalThis.crypto;
|
|
52
|
+
if (!crypto || !crypto.subtle) {
|
|
53
|
+
throw new Error("Web Crypto API is not available in this environment");
|
|
54
|
+
}
|
|
55
|
+
const sharedBits = await crypto.subtle.deriveBits(
|
|
56
|
+
{ name: "ECDH", public: theirPub },
|
|
57
|
+
myPriv,
|
|
58
|
+
256
|
|
59
|
+
);
|
|
60
|
+
return jose.base64url.encode(new Uint8Array(sharedBits));
|
|
61
|
+
}
|
|
62
|
+
static async encrypt(text, sessionKey) {
|
|
63
|
+
const key = await this._stringToKey(sessionKey);
|
|
64
|
+
const enc = new TextEncoder();
|
|
65
|
+
return await new jose.CompactEncrypt(enc.encode(text)).setProtectedHeader({ alg: "dir", enc: "A256GCM" }).encrypt(key);
|
|
66
|
+
}
|
|
67
|
+
static async decrypt(cipherText, sessionKey) {
|
|
68
|
+
const key = await this._stringToKey(sessionKey);
|
|
69
|
+
const { plaintext } = await jose.compactDecrypt(cipherText, key);
|
|
70
|
+
return new TextDecoder().decode(plaintext);
|
|
71
|
+
}
|
|
72
|
+
static async _stringToKey(str) {
|
|
73
|
+
return jose.importJWK(
|
|
74
|
+
{ kty: "oct", k: str, alg: "A256GCM", ext: true },
|
|
75
|
+
"A256GCM"
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
};
|
|
79
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
80
|
+
0 && (module.exports = {
|
|
81
|
+
KushE2E
|
|
82
|
+
});
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import * as jose from "jose";
|
|
3
|
+
var KushE2E = class {
|
|
4
|
+
static async createIdentity() {
|
|
5
|
+
const { publicKey, privateKey } = await jose.generateKeyPair("ECDH-ES+A256KW", {
|
|
6
|
+
crv: "P-256",
|
|
7
|
+
extractable: true
|
|
8
|
+
});
|
|
9
|
+
return {
|
|
10
|
+
publicKey: await jose.exportSPKI(publicKey),
|
|
11
|
+
privateKey: await jose.exportPKCS8(privateKey)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
static async deriveSessionKey(myPrivateKeyPem, theirPublicKeyPem) {
|
|
15
|
+
const myPriv = await jose.importPKCS8(myPrivateKeyPem, "ECDH-ES+A256KW");
|
|
16
|
+
const theirPub = await jose.importSPKI(theirPublicKeyPem, "ECDH-ES+A256KW");
|
|
17
|
+
const crypto = globalThis.crypto;
|
|
18
|
+
if (!crypto || !crypto.subtle) {
|
|
19
|
+
throw new Error("Web Crypto API is not available in this environment");
|
|
20
|
+
}
|
|
21
|
+
const sharedBits = await crypto.subtle.deriveBits(
|
|
22
|
+
{ name: "ECDH", public: theirPub },
|
|
23
|
+
myPriv,
|
|
24
|
+
256
|
|
25
|
+
);
|
|
26
|
+
return jose.base64url.encode(new Uint8Array(sharedBits));
|
|
27
|
+
}
|
|
28
|
+
static async encrypt(text, sessionKey) {
|
|
29
|
+
const key = await this._stringToKey(sessionKey);
|
|
30
|
+
const enc = new TextEncoder();
|
|
31
|
+
return await new jose.CompactEncrypt(enc.encode(text)).setProtectedHeader({ alg: "dir", enc: "A256GCM" }).encrypt(key);
|
|
32
|
+
}
|
|
33
|
+
static async decrypt(cipherText, sessionKey) {
|
|
34
|
+
const key = await this._stringToKey(sessionKey);
|
|
35
|
+
const { plaintext } = await jose.compactDecrypt(cipherText, key);
|
|
36
|
+
return new TextDecoder().decode(plaintext);
|
|
37
|
+
}
|
|
38
|
+
static async _stringToKey(str) {
|
|
39
|
+
return jose.importJWK(
|
|
40
|
+
{ kty: "oct", k: str, alg: "A256GCM", ext: true },
|
|
41
|
+
"A256GCM"
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
export {
|
|
46
|
+
KushE2E
|
|
47
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kush-e2e",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "End-to-end encryption library for secure peer-to-peer communication",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.mjs",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
10
|
+
"dev": "tsup src/index.ts --format cjs,esm --dts --watch"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"e2e",
|
|
14
|
+
"encryption",
|
|
15
|
+
"ecdh",
|
|
16
|
+
"aes",
|
|
17
|
+
"crypto",
|
|
18
|
+
"secure",
|
|
19
|
+
"messaging"
|
|
20
|
+
],
|
|
21
|
+
"author": "",
|
|
22
|
+
"license": "ISC",
|
|
23
|
+
"type": "commonjs",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/kushkumarkashyap7280/kush-e2e"
|
|
27
|
+
},
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/kushkumarkashyap7280/kush-e2e/issues"
|
|
30
|
+
},
|
|
31
|
+
"homepage": "https://github.com/kushkumarkashyap7280/kush-e2e#readme",
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"jose": "^6.1.3",
|
|
34
|
+
"tsup": "^8.5.1",
|
|
35
|
+
"typescript": "^5.9.3"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"@types/node": "^25.2.0"
|
|
39
|
+
}
|
|
40
|
+
}
|