← Back to list

KriPoint: How I Built an Open-Source Library to Encrypt HTTP Payloads Between Axios and ASP.NET

Stop exposing sensitive data in your browser’s network tab — here’s how KriPoint fixes that with AES-256-CBC encryption, an axios…

Joever Monceda · 2026-05-25 09:21 · 0 claps · 4.4 min read paywalled
#encryption #backend-encryption #frontend-encryption #aes-256-cbc #npm
Open on Medium ↗
Wiki topics: 🌐 · Web Development 🔒 · Cybersecurity 🔓 · Open Source 📚 · Books & Reading

KriPoint: How I Built an Open-Source Library to Encrypt HTTP Payloads Between Axios and ASP.NET Core 8

Stop exposing sensitive data in your browser’s network tab — here’s how KriPoint fixes that with AES-256-CBC encryption, an axios interceptor, and a .NET middleware.

https://youtu.be/d0omzJcJr-c

The Problem

Every developer has been there. You open Chrome DevTools, go to the Network tab, click on a POST request, and see this:

{
 "email": "joever@sample.com",
 "salary": 1000,
 "role": "admin",
 "password": "supersecret123"
}

Plain. Readable. Exposed. Even with HTTPS, your payload is fully visible to anyone who has access to the browser — a user, a tester, a malicious script running in the same tab. For enterprise applications handling sensitive data like salaries, personal information, medical records, or financial transactions, this is a real problem.

I built KriPoint to solve this with a single clean abstraction: encrypt the payload before it leaves the browser, decrypt it transparently on the server. No controller changes. No special DTOs. Just two lines of setup.

What is KriPoint?

KriPoint is a dual-package library:

  • **kripoint** — an NPM package that hooks into Axios via interceptors
  • **KriPoint** — a NuGet package that adds ASP.NET Core 8 middleware

Together they ensure that every HTTP request body is AES-256-CBC encrypted before it hits the wire, and decrypted transparently on the backend before it reaches your controllers.

{
  "payload": "Xk92mP3zR7tL8nQw...",
  "iv":      "aBcD1234efGH5678=="
}

What your controller receives:

CreateUserRequest {
    Email:  "joever@sample.com",
    Salary: 1000,
    Role:   "admin"
}

The Concept: Shared Key Encryption

KriPoint uses AES-256-CBC (Advanced Encryption Standard, 256-bit key, Cipher Block Chaining mode). Both the front-end and back-end share the same secret key — think of it like a padlock where both sides have a copy.

Browser                              Server
────────────────────────────────     ────────────────────────────────
Plain object                         Plain DTO
{ email: "joever@corp.com" }          { Email: "joever@corp.com" }
        │                                    ▲
        │ encrypt(value, key)                │ decrypt(payload, iv, key)
        ▼                                    │
{ payload: "Xk92...", iv: "aB3f..." } ───────┘
            (wire)

Each request generates a fresh random IV (Initialization Vector) — a 16-byte random value that ensures the same plaintext produces a completely different ciphertext every single time. Even if you post the same data 100 times, each encrypted payload looks different.

How It Works

The Wire Format

Every encrypted request follows this contract:

json{
  "payload": "<Base64-encoded AES-256-CBC ciphertext>",
  "iv":      "<Base64-encoded 16-byte IV>"
}

The IV — Why It Matters

The IV is not a secret — it travels alongside the payload. Its purpose is to guarantee that encrypting the same data twice never produces the same ciphertext. Without it, an attacker watching your network could detect patterns even without knowing the key.

Think of it like a salt in password hashing: not secret, but essential for security.

Building the NPM Package

The core of the NPM package is a thin wrapper around the Web Crypto API — available in all modern browsers and Node.js 18+, with no external dependencies.

const ALGO = "AES-CBC";

export async function encrypt(value, base64Key) {
  const key = await importKey(base64Key);
  const iv = crypto.getRandomValues(new Uint8Array(16));
  const plain = new TextEncoder().encode(JSON.stringify(value));
  const cipher = await crypto.subtle.encrypt({ name: ALGO, iv }, key, plain);
  return { payload: toBase64(cipher), iv: toBase64(iv) };
}

export async function decrypt(payload, iv, base64Key) {
  const key = await importKey(base64Key);
  const plain = await crypto.subtle.decrypt(
    { name: ALGO, iv: fromBase64(iv) },
    key,
    fromBase64(payload)
  );
  return JSON.parse(new TextDecoder().decode(plain));
}

No npm dependencies. No polyfills. Just the native browser API.

The Axios Interceptor

The real power of KriPoint is how seamlessly it integrates. You attach it once to your Axios instance and never think about encryption again:

import axios from "axios";
import { attachKriPointInterceptor } from "kripoint";

export const api = axios.create({ baseURL: "https://api.yourapp.com" });

attachKriPointInterceptor(api, {
  key: import.meta.env.VITE_KRIPOINT_KEY,
});

From this point, every api.post(), api.put(), api.patch(), and api.delete() call automatically encrypts its body before Axios sends it. Your application code stays exactly the same:

await api.post("/api/users", {
  email:  "joever@sample.com",
  salary: 95000,
  role:   "admin",
});

The interceptor handles the encrypt → wrap → send cycle invisibly. GET requests are skipped automatically since they carry no body.

Building the .NET 8 NuGet Package

The .NET side is designed around a single principle: zero controller changes. The middleware intercepts the request, decrypts the body, and replaces the request stream with plain JSON — before routing ever touches it.

The Middleware

public async Task InvokeAsync(HttpContext context)
{
    // Read the raw { payload, iv } body
    var rawBody = await ReadBodyAsync(context.Request);

    // Deserialise the envelope
    var envelope = JsonSerializer.Deserialize<KriPointPayload>(rawBody);

    // Decrypt and get plain JSON
    var decryptedJson = _encryption.DecryptToJson(envelope);

    // Replace the request body stream
    var decryptedBytes = Encoding.UTF8.GetBytes(decryptedJson);
    context.Request.Body = new MemoryStream(decryptedBytes);
    context.Request.ContentLength = decryptedBytes.Length;
    context.Request.ContentType = "application/json; charset=utf-8";

    await _next(context);
}

The key insight: by replacing context.Request.Body with a new MemoryStream containing the decrypted JSON, every downstream component — model binding, [FromBody], minimal APIs — sees plain data. No attributes on controllers. No special DTOs.

Two-Line Setup

// Program.cs
builder.Services.AddKriPoint(builder.Configuration);

app.UseKriPoint(); // before MapControllers()
app.MapControllers();
[HttpPost]
public IActionResult Create([FromBody] CreateUserRequest request)
{
    // request.Email, request.Salary are already decrypted
    return Ok(new { request.Email });
}

Key Generation

Generate a shared key once during project setup:

import { generateBase64Key } from "kripoint";
console.log(await generateBase64Key());
// → "abc123XYZ...base64...=="  (32 bytes / 256 bits)

Store it in:

  • Front-end: .envVITE_KRIPOINT_KEY=abc123...
  • Back-end: appsettings.jsonKriPoint.AesKey

Both must have the exact same key. Never commit either to source control.

Security Considerations

KriPoint is defence-in-depth — not a replacement for HTTPS.

What’s Next

KriPoint currently uses AES-256-CBC. The next planned upgrade is AES-256-GCM, which adds built-in authentication — meaning the server can detect if a payload was tampered with in transit, not just fail to decrypt it. GCM is the modern industry recommendation and the migration is non-breaking since the Web Crypto API handles the auth tag automatically.

Other planned features:

  • Response encryption support
  • Key rotation helpers
  • TypeScript-first rewrite of the NPM package
  • .NET 9 support

Getting Started

# NPM
npm install kripoint axios

# .NET
dotnet add package KriPoint

GitHub: https://github.com/Ethan0007/KriPoint NPM: https://www.npmjs.com/package/kripoint NuGet: https://www.nuget.org/packages/KriPoint

Looking for Enterprise Software Engineering in Cagayan de Oro?

**RePoint Solutions Inc.** builds modern, scalable systems using C# and .NET. Let’s build something powerful together.

The Author

https://github.com/Ethan0007 https://joever-monceda.medium.com https://www.linkedin.com/in/joever-monceda-55242779 https://stackoverflow.com/users/7573682/joever-e-monceda https://www.nuget.org/profiles/joever.monceda

If this was useful, give KriPoint a ⭐ on GitHub. Feedback, issues, and PRs are very welcome.


메타데이터
post_id
dc24c4c2d7c6
slug
kripoint-how-i-built-an-open-source-library-to-encrypt-http-payloads-between-axios-and-asp-net-dc24c4c2d7c6
url
https://medium.com/@joever-monceda/kripoint-how-i-built-an-open-source-library-to-encrypt-http-payloads-between-axios-and-asp-net-dc24c4c2d7c6
canonical_url
https://medium.com/@joever-monceda/kripoint-how-i-built-an-open-source-library-to-encrypt-http-payloads-between-axios-and-asp-net-dc24c4c2d7c6
author_url
https://medium.com/@joever-monceda
status
ok
fetched_at
2026-06-09 15:37:30