boro-shield
v1.0.0
Published
Zero-dependency invisible DCT image watermarking and provenance verification. Pure Node.js — no native addons, no external packages.
Maintainers
Readme
🛡️ Boro-Shield
Zero-dependency invisible image watermarking and provenance verification for Node.js.
No sharp. No canvas. No native addons. Pure JavaScript — runs anywhere Node.js runs.
Embeds owner identity into DCT frequency coefficients. The watermark survives cropping, re-compression, and screenshots — and cannot be forged without your secret key.
Installation
npm install boro-shieldNo peer dependencies. Nothing else needed.
Supported Formats
| Format | Support |
|--------|---------|
| BMP (24-bit) | ✅ Native — zero deps |
| PPM (P6) | ✅ Native |
| JPEG / PNG / WebP | ⚙️ Auto via convertAndProtect() — needs ImageMagick or ffmpeg |
To install ImageMagick: sudo apt install imagemagick / brew install imagemagick
Quick Start
import { BoroShield } from 'boro-shield';
import { readFileSync } from 'fs';
const shield = new BoroShield({ secretKey: process.env.SHIELD_SECRET });
// BMP directly (zero deps)
const { protectedBuffer, fingerprint } = await shield.protect(
readFileSync('photo.bmp'),
{ ownerId: 'user_123', location: '9.03,38.74' }
);
// JPEG/PNG (auto-converts using ImageMagick/ffmpeg)
const { protectedBuffer } = await shield.convertAndProtect(
readFileSync('photo.jpg'),
{ ownerId: 'user_123' }
);
// Verify any upload
const result = await shield.verify(readFileSync('uploaded.bmp'));
if (result.isAuthentic) {
console.log('Owner:', result.payload.ownerId);
}
// Duplicate detection
const { isDuplicate } = await shield.compare(bufA, bufB);API
| Method | Description |
|--------|-------------|
| protect(bmpBuf, payload) | Watermark BMP/PPM natively |
| convertAndProtect(anyBuf, payload) | Auto-convert + watermark |
| verify(buf) | Extract and verify watermark |
| audit(buf) | Detect Photoshop edits, AI generation, social media downloads |
| fingerprint(buf) | Get signed perceptual hash for DB storage |
| compare(bufA, bufB) | Duplicate detection via pHash Hamming distance |
Config
new BoroShield({
secretKey: process.env.SHIELD_SECRET, // required, min 16 chars
watermarkDensity: 0.7, // 0–1, how many blocks to use
sensitivity: 10, // Hamming distance threshold for duplicates
strength: 5, // DCT modification strength
})Generate a secret: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
How It Works
- Your payload (ownerId, location, etc.) is signed with HMAC-SHA256
- The signed token is converted to a bitstream
- A secret-seeded PRNG picks scattered 8×8 pixel blocks
- Each block: forward DCT → encode bits into mid-frequency coefficients → inverse DCT
- Repeated N times across the image (redundancy — survives cropping)
- On verify: same PRNG → same blocks → decode bits → verify HMAC signature
License
MIT — by Yohannes
