{"_id":"@amirafa/encryption-service","_rev":"8-65a2adf644bc560ca6716ad7a87a64a5","name":"@amirafa/encryption-service","dist-tags":{"latest":"1.0.6"},"versions":{"1.0.0":{"name":"@amirafa/encryption-service","version":"1.0.0","keywords":["E2EE","EncryptionService","ECDH","AES-GCM"],"author":{"name":"Amirafa","email":"amir.h.rafati@gmail.com"},"license":"MIT","_id":"@amirafa/encryption-service@1.0.0","maintainers":[{"name":"amirafa","email":"amir.h.rafati@gmail.com"}],"dist":{"shasum":"50640ee81f595fd0d28a15dd27cf572f016757b9","tarball":"https://registry.npmjs.org/@amirafa/encryption-service/-/encryption-service-1.0.0.tgz","fileCount":7,"integrity":"sha512-qZBpk5omF8PPC+Oop/VLJdz1/w7fLWcdf/HKljGcj1xBMEaOt0mDEl8ruV3kP7zCe49XbavfN0DmXB5dWDPQOw==","signatures":[{"sig":"MEQCIC5vkTXJkLZlsxKPponOPnoMbf1mhhlMDC9LVfTc30+vAiB3qiqPdamHujd+VDatvb/AglN0WgMck8zHFmLrt4ZSPw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44636},"main":"./dist/encryption-service.umd.js","type":"module","module":"./dist/encryption-service.es.js","exports":{".":{"import":"./dist/encryption-service.es.js","require":"./dist/encryption-service.umd.js"}},"gitHead":"7c116dd1657b1005e3df8eaea7bedf12864d26ed","scripts":{"build":"vite build","typecheck":"tsc --noEmit"},"_npmUser":{"name":"amirafa","email":"amir.h.rafati@gmail.com"},"_npmVersion":"11.4.1","description":"An Encryption Servic library built with Vite","directories":{},"_nodeVersion":"22.11.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.4.0","typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/encryption-service_1.0.0_1761466845436_0.9919501587292154","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@amirafa/encryption-service","version":"1.0.1","keywords":["E2EE","EncryptionService","ECDH","AES-GCM"],"author":{"name":"Amirafa","email":"amir.h.rafati@gmail.com"},"license":"MIT","_id":"@amirafa/encryption-service@1.0.1","maintainers":[{"name":"amirafa","email":"amir.h.rafati@gmail.com"}],"homepage":"https://github.com/amirafa/encrytion-service#readme","bugs":{"url":"https://github.com/amirafa/encrytion-service/issues"},"dist":{"shasum":"f851ba20be290470e184048753ba238e276d8148","tarball":"https://registry.npmjs.org/@amirafa/encryption-service/-/encryption-service-1.0.1.tgz","fileCount":7,"integrity":"sha512-L+LpTb7DQpjUJv/J6ZqKSZM5W5H3geZ0TAiboQmpjsPrY1gE9Or/I+sgOGU7NwCsbpWgyzY/3mKseacpUWAbvg==","signatures":[{"sig":"MEQCIHzyaA60IwE1OYVfe+F55CK0MDgr5BKOeSwt5xNcmL9uAiA0KjUbe8VDGLxg8KBWDTErqzPfV0lxFklNm0jI9Ux5FA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44896},"main":"./dist/encryption-service.umd.js","type":"module","module":"./dist/encryption-service.es.js","exports":{".":{"import":"./dist/encryption-service.es.js","require":"./dist/encryption-service.umd.js"}},"gitHead":"e3a62a7238dfb1bd73d89394dcf103eac88f3465","scripts":{"build":"vite build","typecheck":"tsc --noEmit"},"_npmUser":{"name":"amirafa","email":"amir.h.rafati@gmail.com"},"repository":{"url":"git+https://github.com/amirafa/encrytion-service.git","type":"git"},"_npmVersion":"11.4.1","description":"An Encryption Servic library built with Vite","directories":{},"_nodeVersion":"22.11.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.4.0","typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/encryption-service_1.0.1_1761467050548_0.5463650013231078","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@amirafa/encryption-service","version":"1.0.2","keywords":["E2EE","EncryptionService","ECDH","AES-GCM"],"author":{"name":"Amirafa","email":"amir.h.rafati@gmail.com"},"license":"MIT","_id":"@amirafa/encryption-service@1.0.2","maintainers":[{"name":"amirafa","email":"amir.h.rafati@gmail.com"}],"homepage":"https://github.com/amirafa/encrytion-service#readme","bugs":{"url":"https://github.com/amirafa/encrytion-service/issues"},"dist":{"shasum":"bc3867d9b2eb7fc7ad3166236a1a52d94bdb95da","tarball":"https://registry.npmjs.org/@amirafa/encryption-service/-/encryption-service-1.0.2.tgz","fileCount":7,"integrity":"sha512-p2V9ZlOVm4qHT5j0RW26qRg4f9vpvaHE5rBlhCp6G7MvVLGP3mv4BmnzLs8nRVEF88iSwdYlClkq8jIzDswTGg==","signatures":[{"sig":"MEUCIQCdwuADpPm8/Q34ZUxccow0ZGIda4GBT0U9LFBVU25E1AIgNYIPwK5dSLqSb9dGpjOuPXn/b86rqrpggWClpJFN+ZI=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":44897},"main":"./dist/encryption-service.umd.js","type":"module","module":"./dist/encryption-service.es.js","exports":{".":{"import":"./dist/encryption-service.es.js","require":"./dist/encryption-service.umd.js"}},"gitHead":"349f26cdaefc0ae38fc235272cf514fb0ec96330","scripts":{"build":"vite build","typecheck":"tsc --noEmit"},"_npmUser":{"name":"amirafa","email":"amir.h.rafati@gmail.com"},"repository":{"url":"git+https://github.com/amirafa/encrytion-service.git","type":"git"},"_npmVersion":"11.4.1","description":"An Encryption Service library built with Vite","directories":{},"_nodeVersion":"22.11.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.4.0","typescript":"^5.6.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/encryption-service_1.0.2_1761467112238_0.7156105228494141","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@amirafa/encryption-service","version":"1.0.3","keywords":["E2EE","EncryptionService","ECDH","AES-GCM"],"author":{"name":"Amirafa","email":"amir.h.rafati@gmail.com"},"license":"MIT","_id":"@amirafa/encryption-service@1.0.3","maintainers":[{"name":"amirafa","email":"amir.h.rafati@gmail.com"}],"homepage":"https://github.com/amirafa/encrytion-service#readme","bugs":{"url":"https://github.com/amirafa/encrytion-service/issues"},"dist":{"shasum":"facda842d30e3c6d0c66d3505747589891c8a4c4","tarball":"https://registry.npmjs.org/@amirafa/encryption-service/-/encryption-service-1.0.3.tgz","fileCount":6,"integrity":"sha512-hT2dZMyGhMqOu5KqPQaErrvDDa+xkXbLzcGiGM7o8DtZVpBKw+jbdh5GTzo9euINTio9a7Uqg06LpVYWwDRhRw==","signatures":[{"sig":"MEQCIAnPXY0AxFi3cJUw7xD48xhw+O7bo/x3M6TyviNPXMyVAiA3eshxHd5k57iG34NFcKwAOimncVfRImPKgXXae2w7tA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":21561},"main":"./dist/encryption-service.umd.js","type":"module","types":"./dist/encryption-service.d.ts","module":"./dist/encryption-service.es.js","exports":{".":{"types":"./dist/encryption-service.d.ts","import":"./dist/encryption-service.es.js","require":"./dist/encryption-service.umd.js"}},"gitHead":"10ab2aea44d59653ea84087cf935a6f55eb541f8","scripts":{"build":"vite build","typecheck":"tsc --noEmit"},"_npmUser":{"name":"amirafa","email":"amir.h.rafati@gmail.com"},"repository":{"url":"git+https://github.com/amirafa/encrytion-service.git","type":"git"},"_npmVersion":"11.4.1","description":"An Encryption Service library built with Vite","directories":{},"_nodeVersion":"22.11.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.4.21","typescript":"^5.9.3","@types/node":"^22.0.0","vite-plugin-dts":"^4.5.4"},"_npmOperationalInternal":{"tmp":"tmp/encryption-service_1.0.3_1761479143784_0.8147000482085824","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@amirafa/encryption-service","version":"1.0.5","keywords":["E2EE","EncryptionService","ECDH","AES-GCM"],"author":{"name":"Amirafa","email":"amir.h.rafati@gmail.com"},"license":"MIT","_id":"@amirafa/encryption-service@1.0.5","maintainers":[{"name":"amirafa","email":"amir.h.rafati@gmail.com"}],"homepage":"https://github.com/amirafa/encrytion-service#readme","bugs":{"url":"https://github.com/amirafa/encrytion-service/issues"},"dist":{"shasum":"581be052b1bf740bbd85cd7d7d8919db39088fb3","tarball":"https://registry.npmjs.org/@amirafa/encryption-service/-/encryption-service-1.0.5.tgz","fileCount":6,"integrity":"sha512-A9hYlyyEOc8y10dNfb4NHu9LFyiVw8kp6coc7zhjlYjnXBtnZaOPwZtTSBTFK5uuS2nIFEV5GaWKsp+eKHXmvg==","signatures":[{"sig":"MEQCIAGHgmJ0Y6t91+HceD8iwTej/pv2YWR7L5vir4SL+wVHAiAm8ZjCk58kix7uynKBfCJdVfatBQuNQLQiy2CD2rCezg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":22409},"main":"./dist/encryption-service.umd.js","type":"module","types":"./dist/encryption-service.d.ts","module":"./dist/encryption-service.es.js","exports":{".":{"types":"./dist/encryption-service.d.ts","import":"./dist/encryption-service.es.js","require":"./dist/encryption-service.umd.js"}},"gitHead":"e33ea164fbbb62358ee0392a192a2ef931ac971c","scripts":{"build":"vite build","typecheck":"tsc --noEmit"},"_npmUser":{"name":"amirafa","email":"amir.h.rafati@gmail.com"},"repository":{"url":"git+https://github.com/amirafa/encrytion-service.git","type":"git"},"_npmVersion":"11.4.0","description":"An Encryption Service library built with Vite","directories":{},"_nodeVersion":"22.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"^5.4.21","typescript":"^5.9.3","@types/node":"^22.0.0","vite-plugin-dts":"^4.5.4"},"_npmOperationalInternal":{"tmp":"tmp/encryption-service_1.0.5_1761504238208_0.622992677544937","host":"s3://npm-registry-packages-npm-production"}},"1.0.6":{"name":"@amirafa/encryption-service","version":"1.0.6","description":"An Encryption Service library built with Vite","license":"MIT","author":{"name":"Amirafa","email":"amir.h.rafati@gmail.com"},"keywords":["E2EE","EncryptionService","ECDH","AES-GCM"],"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/amirafa/encryption-service.git"},"bugs":{"url":"https://github.com/amirafa/encryption-service/issues"},"homepage":"https://github.com/amirafa/encryption-service#readme","main":"./dist/encryption-service.umd.js","module":"./dist/encryption-service.es.js","types":"./dist/encryption-service.d.ts","exports":{".":{"import":"./dist/encryption-service.es.js","require":"./dist/encryption-service.umd.js","types":"./dist/encryption-service.d.ts"}},"scripts":{"build":"vite build","typecheck":"tsc --noEmit"},"devDependencies":{"@types/node":"^22.0.0","typescript":"^5.9.3","vite":"^5.4.21","vite-plugin-dts":"^4.5.4"},"type":"module","_id":"@amirafa/encryption-service@1.0.6","gitHead":"aaee8a2b590dbf344c306b66dc4bfd993e6a4952","_nodeVersion":"22.11.0","_npmVersion":"11.4.1","dist":{"integrity":"sha512-ToLHDjGnc9+zy81VgQQhELRnUYp92i2QuSLzDwSNpsNn2jSY4/isyfrr2koKXbB4UDeUKcJFvz6DP2bx/73T9A==","shasum":"b45c4e8ffadd51b364aaec03a7ff4b5e683a7aa6","tarball":"https://registry.npmjs.org/@amirafa/encryption-service/-/encryption-service-1.0.6.tgz","fileCount":6,"unpackedSize":22023,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCsY2/UiessguMCIiSf3/D5b69/zFsjD82KEYCD8EWARgIhALeWtPNuyCX2bSkoOxz3hFcVVnwp9gYzrzihjtU8u3I1"}]},"_npmUser":{"name":"amirafa","email":"amir.h.rafati@gmail.com"},"directories":{},"maintainers":[{"name":"amirafa","email":"amir.h.rafati@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/encryption-service_1.0.6_1761637165739_0.04147098518492931"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-26T08:20:45.325Z","modified":"2025-10-28T07:39:26.128Z","1.0.0":"2025-10-26T08:20:45.631Z","1.0.1":"2025-10-26T08:24:10.785Z","1.0.2":"2025-10-26T08:25:12.441Z","1.0.3":"2025-10-26T11:45:44.013Z","1.0.4":"2025-10-26T12:00:53.019Z","1.0.5":"2025-10-26T18:43:58.385Z","1.0.6":"2025-10-28T07:39:25.948Z"},"bugs":{"url":"https://github.com/amirafa/encryption-service/issues"},"author":{"name":"Amirafa","email":"amir.h.rafati@gmail.com"},"license":"MIT","homepage":"https://github.com/amirafa/encryption-service#readme","keywords":["E2EE","EncryptionService","ECDH","AES-GCM"],"repository":{"type":"git","url":"git+https://github.com/amirafa/encryption-service.git"},"description":"An Encryption Service library built with Vite","maintainers":[{"name":"amirafa","email":"amir.h.rafati@gmail.com"}],"readme":"<p align=\"center\">\n  <a href='https://postimages.org/' target='_blank'>\n    <img \n      src='https://i.postimg.cc/mrBJJjMJ/Encryption-Service-logo.png'       \n      width=\"250\" \n      height=\"250\"  \n      border='0' \n      alt='vuexp-logo'\n    />\n  </a>\n</p>\n\n# Encryption Service\n\nA lightweight library to use E2EE\n\n## 🚀 Installation\n\n### From npm\n```bash\nnpm install @amirafa/encryption-service\n```\n\n### From yarn\n```bash\nyarn add @amirafa/encryption-service\n```\n\n### From pnpm\n```bash\npnpm add @amirafa/encryption-service\n```\n\n---\n\n## 🧩 Import and Usage\n\n```ts\nimport { EncryptionService } from \"@amirafa/encryption-service\";\n\nconst enc = EncryptionService();\n\n// generate user keys\nawait enc.generateAndStoreIdentityKeyPair(\"alice\");\nawait enc.generateAndStoreECDHKeyPair(\"alice\");\n\n// example: encrypt and decrypt a message\nconst alicePriv = await enc.importPrivateKey(localStorage.getItem(\"alice-privateKey\")!);\nconst bobPub = await enc.importPublicKey(localStorage.getItem(\"bob-publicKey\")!);\n\nconst sharedKey = await enc.deriveSharedKey(alicePriv, bobPub);\n\nconst { encryptedMessage, iv } = await enc.encryptMessageAES(\"Hello Bob!\", sharedKey);\nconst plain = await enc.decryptMessageAES(encryptedMessage, sharedKey, iv);\n\nconsole.log(plain); // \"Hello Bob!\"\n```\n\n---\n\n# Full Flow & Backend Schema\n\nThis document describes how the `EncryptionServiceClass` implements **end-to-end encryption (E2EE)** for a secure chat system and how the **backend** should store and handle related data.\n\n---\n\n## 🧩 Architecture Overview\n\nThe system uses three cryptographic layers:\n\n1. **ECDSA (Identity)** — for signing and verifying identity keys.  \n2. **ECDH (Shared Key)** — for deriving a mutual secret key between two users.  \n3. **AES-GCM (Message Encryption)** — for encrypting and decrypting messages.\n\nAll encryption/decryption logic happens **in the browser (client-side)**.  \nThe backend only stores **public keys**, **signatures**, and **encrypted data** — never plaintext or private keys.\n\n---\n\n## 🧱 Function Reference (Client-Side)\n\n### `generateAndStoreIdentityKeyPair(username)`\nGenerates an **ECDSA key pair** (identity keys) and stores both in `localStorage`.\n\n```ts\nawait enc.generateAndStoreIdentityKeyPair(\"alice\");\n```\n\nStored keys:\n```\nalice-id-publicKey\nalice-id-privateKey\n```\n\n---\n\n### `generateAndStoreECDHKeyPair(username)`\nGenerates an **ECDH key pair** for secure message key exchange.\n\n```ts\nawait enc.generateAndStoreECDHKeyPair(\"alice\");\n```\n\nStored keys:\n```\nalice-publicKey\nalice-privateKey\n```\n\n---\n\n### `signEcdhPublicKey(identityPriv, ecdhPub)`\nSigns the ECDH public key using the identity private key (ECDSA).\n\n```ts\nconst sig = await enc.signEcdhPublicKey(aliceIdPriv, aliceEcdhPub);\n```\n\n---\n\n### `verifyEcdhPublicKeySignature(identityPub, ecdhPub, signature)`\nVerifies that an ECDH public key truly belongs to a given identity.\n\n```ts\nconst ok = await enc.verifyEcdhPublicKeySignature(bobIdPub, bobEcdhPub, sig);\n```\n\n---\n\n### `deriveSharedKey(privateKey, publicKey)`\nDerives a shared AES key using your **private ECDH key** and the other user’s **public ECDH key**.\n\n```ts\nconst aesKey = await enc.deriveSharedKey(alicePrivEcdh, bobPubEcdh);\n```\n\nBoth sides independently derive **the same AES key**.\n\n---\n\n### `encryptMessageAES(message, aesKey)`\nEncrypts a plaintext message using AES-GCM.\n\n```ts\nconst { encryptedMessage, iv } = await enc.encryptMessageAES(\"Hello Bob\", aesKey);\n```\n\n`iv` (Initialization Vector) must be sent along with the ciphertext.\n\n---\n\n### `decryptMessageAES(encryptedMessage, aesKey, iv)`\nDecrypts a message using the same AES key and IV.\n\n```ts\nconst plain = await enc.decryptMessageAES(encryptedMessage, aesKey, iv);\n```\n\n---\n\n### `getIdentityFingerprint(identityPub)`\nGenerates a SHA-256 fingerprint of an identity key for display and manual verification (TOFU).\n\n```ts\nconst fpr = await enc.getIdentityFingerprint(aliceIdentityPub);\nconsole.log(\"Alice fingerprint:\", fpr);\n```\n\n---\n\n## 🧭 Full Message Exchange Flow\n\n### 1️⃣ Key Generation (first time only)\n```ts\nawait enc.generateAndStoreIdentityKeyPair(\"alice\");\nawait enc.generateAndStoreECDHKeyPair(\"alice\");\n\nawait enc.generateAndStoreIdentityKeyPair(\"bob\");\nawait enc.generateAndStoreECDHKeyPair(\"bob\");\n```\n\n---\n\n### 2️⃣ Alice signs her ECDH key\n```ts\nconst idPriv = await enc.importIdentityPrivateKey(localStorage.getItem(\"alice-id-privateKey\")!);\nconst ecdhPub = await enc.importPublicKey(localStorage.getItem(\"alice-publicKey\")!);\nconst signature = await enc.signEcdhPublicKey(idPriv, ecdhPub);\n\nconst alicePackage = {\n  identityPublicKey: localStorage.getItem(\"alice-id-publicKey\")!,\n  ecdhPublicKey: localStorage.getItem(\"alice-publicKey\")!,\n  signature\n};\n```\nAlice sends this JSON package to Bob via the server.\n\n---\n\n### 3️⃣ Bob verifies Alice’s identity\n```ts\nconst aliceIdPub = await enc.importIdentityPublicKey(alicePackage.identityPublicKey);\nconst aliceEcdhPub = await enc.importPublicKey(alicePackage.ecdhPublicKey);\nconst valid = await enc.verifyEcdhPublicKeySignature(aliceIdPub, aliceEcdhPub, alicePackage.signature);\nif (!valid) throw new Error(\"Fake Alice detected!\");\n```\n\n---\n\n### 4️⃣ Both derive the shared AES key\n```ts\nconst bobPriv = await enc.importPrivateKey(localStorage.getItem(\"bob-privateKey\")!);\nconst sharedKey = await enc.deriveSharedKey(bobPriv, aliceEcdhPub);\n```\n\nBoth parties now hold the same symmetric AES key.\n\n---\n\n### 5️⃣ Alice encrypts and sends the message\n```ts\nconst { encryptedMessage, iv } = await enc.encryptMessageAES(\"Hi Bob!\", sharedKey);\nconst chatEntry = {\n  sender: \"alice\",\n  recipient: \"bob\",\n  message: Array.from(new Uint8Array(encryptedMessage)),\n  iv: Array.from(iv)\n};\n// send chatEntry to server\n```\n\n---\n\n### 6️⃣ Bob receives and decrypts\n```ts\nconst msgBuf = new Uint8Array(chatEntry.message).buffer;\nconst ivBuf = new Uint8Array(chatEntry.iv);\nconst plain = await enc.decryptMessageAES(msgBuf, sharedKey, ivBuf);\nconsole.log(\"Decrypted:\", plain); // \"Hi Bob!\"\n```\n\n---\n\n## 🗄 Recommended Database Schema (Backend)\n\n### Users Table\n```ts\n{\n  username: string,\n  identityPublicKey: string,\n  ecdhPublicKey: string,\n  signature: string\n}\n```\n\n### Messages Table\n```ts\n{\n  sender: string,\n  recipient: string,\n  message: number[],\n  iv: number[]\n}\n```\n\n---\n\n## 💾 SQL Implementation Example\n\n### `users`\n```sql\nCREATE TABLE users (\n  id SERIAL PRIMARY KEY,\n  username VARCHAR(50) UNIQUE NOT NULL,\n  identity_public_key TEXT NOT NULL,\n  ecdh_public_key TEXT NOT NULL,\n  signature TEXT NOT NULL,\n  created_at TIMESTAMP DEFAULT NOW()\n);\n```\n\n### `messages`\n```sql\nCREATE TABLE messages (\n  id SERIAL PRIMARY KEY,\n  sender VARCHAR(50) NOT NULL,\n  recipient VARCHAR(50) NOT NULL,\n  message BYTEA NOT NULL,\n  iv BYTEA NOT NULL,\n  created_at TIMESTAMP DEFAULT NOW(),\n  FOREIGN KEY (sender) REFERENCES users(username),\n  FOREIGN KEY (recipient) REFERENCES users(username)\n);\n```\n\n---\n\n## 🔄 Example API Flow\n\n### Client → Server (Send Message)\n```json\n{\n  \"sender\": \"alice\",\n  \"recipient\": \"bob\",\n  \"message\": \"BASE64_ENCRYPTED_DATA\",\n  \"iv\": \"BASE64_IV\"\n}\n```\n\n### Server → Client (Retrieve Message)\n```json\n{\n  \"sender\": \"alice\",\n  \"message\": \"BASE64_ENCRYPTED_DATA\",\n  \"iv\": \"BASE64_IV\"\n}\n```\n\n### Client Decrypts\n```ts\nconst msg = await enc.decryptMessageAES(\n  base64ToArrayBuffer(message),\n  aesKey,\n  base64ToUint8Array(iv)\n);\nconsole.log(msg); // \"Hello Bob!\"\n```\n\n---\n\n## 🔒 Security Notes\n\n- The server stores **only public keys** and **encrypted data**.  \n- **Private keys and plaintext** never leave the user’s device.  \n- Messages must be delivered **only to their intended recipient**.  \n- The backend is **zero-knowledge** — even a data leak reveals nothing readable.\n\n---\n\n## ✅ Summary\n\n| Component             | Responsibility              | Location |\n| --------------------- | --------------------------- | -------- |\n| ECDSA                 | Identity and signature      | Client   |\n| ECDH                  | Shared key derivation       | Client   |\n| AES-GCM               | Message encryption/decryption | Client |\n| Key & message storage | Persistence only            | Backend  |\n| Plaintext visibility  | Sender & recipient devices only | — |\n\n---\n\n## 🧾 License\n\nMIT © 2025 — Encryption Service by Amirafa  \nFeel free to use, modify, and distribute under the terms of the MIT license.\n\n---\n\n## Changelog\n\n### [Version 1.0.6] - 2025-10-28\n\n-   Add `git repository`\n\n### [Version 1.0.5] - 2025-10-26\n\n-   Update `README.md`\n-   Add `logo`\n\n### [Version 1.0.3] - 2025-10-26\n\n-   Add `type declaration`\n-   Update `README.md`\n\n### [Version 1.0.2] - 2025-10-26\n\n-   Add `README.md`\n\n### [Version 1.0.1] - 2025-10-26\n\n-   Minor `fixes`\n\n### [Version 1.0.0] - 2025-10-26\n\n-   published `@amirafa/encryption-service`","readmeFilename":"README.md"}