Socket
Book a DemoInstallSign in
Socket

mz.attahri.com/code/ece/v2

Package Overview
Dependencies
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

mz.attahri.com/code/ece/v2

Go Modules
Version
v2.0.0
Version published
Created
Source

GoDoc reference npm version Lint Test

Encrypted-Content-Encoding for HTTP

An implementation of RFC 8188 in Go and JavaScript/TypeScript.

ECE for HTTP defines a way to use standard HTTP content encoding to exchange AES-GCM encrypted payloads between a client and server.

While the RFC only mentions 128-bit encryption with AES-128-GCM, this library provides support for AES-256-GCM as well when a key sufficiently long (32 bytes) is provided.

JavaScript / TypeScript

npm i @mzattahri/ece

See js/README.md for full documentation.

Go

See also: TypeScript/JavaScript implementation

The library exposes 4 basic elements:

  • A Reader to decrypt;
  • A Writer to encrypt;
  • An HTTP middleware to handle server-side encryption/decryption;
  • An HTTP Transport for client-side encryption/decryption.

Reader

Reader deciphers data from a reader (io.Reader) containing encrypted data.

var key []byte            // Main decryption key
var cipher io.ReadCloser  // AES-GCM encrypted data

r := ece.NewReader(key, cipher)
plain, err := io.ReadAll(r)
if err != nil {
  log.Fatalf("error during decryption: %v", err)
}
defer r.Close()

fmt.Println(plain) // plain version of the content of cipher.

Writer

Writer writes encrypted data into another writer (io.Writer).

var key = []byte("16 or 32 bytes long key")   // Main decryption key
var dest io.Writer                            // Where cipher will be written

var (
  salt        = ece.GenerateSalt(rand.Reader)  // Must be random
  recordSize  = 4096                    // Record size
  keyID       = "ID of the main key"    // (Empty string to omit)
)
w, err := ece.NewWriter(key, salt, recordSize, keyID, dest)
if err != nil {
  log.Fatalf("error initializing writer: %v", err)
}
defer w.Close()     // Cipher may be mis-formatted if omitted

if _, err := io.WriteString(w, "Hello, World!"); err != nil {
  log.Fatalf("error writing cipher: %v", err)
}

log.Println("dest now contains encrypted data")

HTTP Handler

Handler is an HTTP middleware you can use to transparently decrypt incoming requests and encrypt outgoing responses.

Incoming requests are decrypted if they come with a header Content-Encoding set to either aes128gcm or aes256gcm. Similarly, responses are encrypted if the request's Accept-Encoding or X-Accept-Encoding headers are set to either value.

h := http.HandlerFunc(
  func(w http.ResponseWriter, r *http.Request) {
    // r.Body now contains plain data if the client sent
    // encrypted request.

    // w.Write will encrypt the data before sending
    // it back.
  },
)

var (
  key = []byte("256-bit long key")
  rs  = 4096
)
http.ListenAndServe(":8000", ece.Handler(key, rs, h))

HTTP Transport

Transport is an http.RoundTripper that handles the encryption of outgoing requests and the decryption of responses. Use it with any http.Client.

Requests are systematically encrypted, while responses are only decrypted if the Content-Encoding header is set to aes128gcm or aes256gcm.

var (
  keyID       = "ID of the key below"              // (Empty string to omit)
  key         = []byte("16 or 32 byte long key")
  payload     = strings.NewReader(`{"key": "value"}`)
)

transport, err := ece.AES128GCM.NewTransport(key, keyID, 4096, nil)
if err != nil {
  log.Fatalf("error initializing transport: %v", err)
}

client := &http.Client{Transport: transport}
resp, err := client.Post("https://api.example.com", "application/json", payload)
if err != nil {
  log.Fatalf("HTTP request failed: %v", err)
}

// payload was encrypted before it was sent

// resp.Body is decrypted if the server returned an encrypted response.
data, err := io.ReadAll(resp.Body)
if err != nil {
  log.Fatalf("error reading response: %v", err)
}

log.Println(data) // plain data

Generating Keys

Use the GenerateKey method on the encoding to create a key of the correct size:

import "crypto/rand"

// 256-bit key (32 bytes)
key256 := ece.AES256GCM.GenerateKey(rand.Reader)

// 128-bit key (16 bytes)
key128 := ece.AES128GCM.GenerateKey(rand.Reader)

Contributions

Contributions are welcome via Pull Requests.

FAQs

Package last updated on 01 Dec 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts