Skip to content
This repository was archived by the owner on Dec 4, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
110 changes: 7 additions & 103 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,14 @@ This project is a monorepo that contains the following packages:

## Features

This package provides two main modes for image fragmentation:
This package provides image fragmentation functionality:

### 🔀 Shuffle Only Mode
- If `secretKey` is not set, only shuffling is performed.
### 🔀 Shuffle Mode

```
Original Image → Load → Convert to RGBA → Shuffle → Fragmented PNG Output
```

### 🔐 Shuffle + Encrypt Mode (Deprecated)
- If `secretKey` is set, both shuffling and encryption are performed.

```
Original Image → Load → Convert to RGBA → Encrypt → Shuffle → Fragmented PNG Output
```

## Installation

```
Expand All @@ -46,11 +38,9 @@ npm i image-shield
import ImageShield from "image-shield";
```

### 🔀 Shuffle Only Mode

If you do not set the `secretKey`, only shuffling will be applied to the images.
### 🔀 Shuffle Mode

**Encrypt**
**Fragment**

```ts
await ImageShield.encrypt({
Expand All @@ -61,7 +51,6 @@ await ImageShield.encrypt({
"./input_3.png",
],
outputDir: "./output/fragmented",
// secretKey: undefined
});
```

Expand Down Expand Up @@ -89,7 +78,7 @@ output

</details>

**Decrypt**
**Restore**

```ts
await ImageShield.decrypt({
Expand All @@ -100,7 +89,6 @@ await ImageShield.decrypt({
"./output/fragmented/img_3_fragmented.png",
],
outputDir: "./output/restored",
// secretKey: undefined
});
```

Expand Down Expand Up @@ -129,88 +117,6 @@ output

---

### 🔐 Shuffle + Encrypt Mode

If you set the `secretKey`, both shuffling and encryption will be applied to the images.

**Encrypt**

```ts
await ImageShield.encrypt({
// config: { /** FragmentationConfig */ },
imagePaths: [
"./input_1.png",
"./input_2.png",
"./input_3.png",
],
outputDir: "./output/fragmented",
secretKey: "secret",
});
```

<details>
<summary>Output:</summary>

```
output
└── fragmented
├── img_1_fragmented.png
├── img_2_fragmented.png
├── img_3_fragmented.png
└── manifest.json
```

| input 1 | input 2 | input 3 |
|:-------:|:---------------:|:---------------:|
| ![](.docs/input_sample.png) | ![](.docs/input_sample_mono.png) | ![](.docs/input_sample_blue.png) |
| 500 x 500px (109KB) | 400 x 600px (4KB) | 600 x 400px (3KB) |

| output 1 | output 2 | output 3 |
|:-------:|:---------------:|:---------------:|
| ![](.docs/fragmented2/img_1_fragmented.png) | ![](.docs/fragmented2/img_2_fragmented.png) | ![](.docs/fragmented2/img_3_fragmented.png) |
| 494 x 494px (976KB) | 494 x 494px (976KB) | 494 x 494px (976KB) |

</details>

**Decrypt**

```ts
await ImageShield.decrypt({
manifestPath: "./output/fragmented/manifest.json",
imagePaths: [
"./output/fragmented/img_1_fragmented.png",
"./output/fragmented/img_2_fragmented.png",
"./output/fragmented/img_3_fragmented.png",
],
outputDir: "./output/restored",
secretKey: "secret",
});
```

<details>
<summary>Output:</summary>

```
output
└── restored
├── img_1.png
├── img_2.png
└── img_3.png
```

| input 1 | input 2 | input 3 |
|:-------:|:---------------:|:---------------:|
| ![](.docs/fragmented2/img_1_fragmented.png) | ![](.docs/fragmented2/img_2_fragmented.png) | ![](.docs/fragmented2/img_3_fragmented.png) |
| 494 x 494px (976KB) | 494 x 494px (976KB) | 494 x 494px (976KB) |

| output 1 | output 2 | output 3 |
|:-------:|:---------------:|:---------------:|
| ![](.docs/restored2/img_1.png) | ![](.docs/restored2/img_2.png) | ![](.docs/restored2/img_3.png) |
| 500 x 500px (117KB) | 400 x 600px (2KB) | 600 x 400px (2KB) |

</details>


## Shuffle Overview

### List by blockSize
Expand Down Expand Up @@ -272,17 +178,15 @@ manifest.json:
"x": 245,
"y": 245
}
],
"algorithm": "aes-256-cbc",
"secure": true
]
}
```
</details>

---

> [!NOTE]
> - The `manifest.json` file contains the necessary information for restoration, but it does not include the secret key.
> - The `manifest.json` file contains the necessary information for restoration.
> - Input images are converted to PNG format.

## Clients
Expand Down
53 changes: 18 additions & 35 deletions packages/cli/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,14 @@ Options:
-h, --help display help for command

Commands:
encrypt [options] <images...> Fragment and encrypt images
encrypt [options] <images...> Fragment images
decrypt [options] <fragments...> Restore fragmented images
help [command] display help for command
```

### Encrypt Command

Fragment and optionally encrypt images into multiple pieces.
Fragment images into multiple pieces.

```bash
image-shield encrypt <images...> -o <output_directory> [options]
Expand All @@ -46,11 +46,10 @@ image-shield encrypt <images...> -o <output_directory> [options]
| Option | Description | Required | Default |
|--------|-------------|----------|---------|
| `-o, --output <dir>` | Output directory for fragments and manifest | ✅ | - |
| `-k, --key <key>` | Secret key for encryption | ❌ | - |
| `-b, --block-size <size>` | Pixel block size (positive integer) | ❌ | 10 |
| `-p, --prefix <prefix>` | Prefix for fragment files | ❌ | "fragment" |
| `-s, --seed <seed>` | Random seed (integer) | ❌ | auto-generated |
| `--restore-filename` | Restore original file names when decrypting | ❌ | false |
| `--restore-filename` | Restore original file names when restoring | ❌ | false |

#### Examples

Expand All @@ -59,11 +58,6 @@ image-shield encrypt <images...> -o <output_directory> [options]
image-shield encrypt image1.jpg image2.png -o ./fragments
```

**With encryption:**
```bash
image-shield encrypt image.jpg -o ./secure-fragments -k mySecretKey123
```

**Custom configuration:**
```bash
image-shield encrypt *.jpg -o ./output -b 20 -p "my_fragment" --restore-filename
Expand All @@ -76,7 +70,7 @@ image-shield encrypt image.png -o ./output -s 12345

#### Output Structure

After encryption, the output directory will contain:
After fragmentation, the output directory will contain:
```
output/
├── manifest.json # Metadata for restoration
Expand All @@ -99,7 +93,6 @@ image-shield decrypt <fragments...> -m <manifest_path> -o <output_directory> [op
|--------|-------------|----------|
| `-m, --manifest <path>` | Path to the manifest.json file | ✅ |
| `-o, --output <dir>` | Output directory for restored images | ✅ |
| `-k, --key <key>` | Secret key for decryption (if encrypted) | ❌ |

#### Examples

Expand All @@ -108,11 +101,6 @@ image-shield decrypt <fragments...> -m <manifest_path> -o <output_directory> [op
image-shield decrypt ./fragments/*.png -m ./fragments/manifest.json -o ./restored
```

**With decryption:**
```bash
image-shield decrypt ./secure-fragments/*.png -m ./secure-fragments/manifest.json -o ./restored -k mySecretKey123
```

**Specific fragments:**
```bash
image-shield decrypt fragment_0000.png fragment_0001.png fragment_0002.png -m manifest.json -o ./output
Expand All @@ -124,7 +112,7 @@ The CLI provides clear error messages for common issues:

- **File not found**: When input images or manifest don't exist
- **Invalid options**: When required options are missing or invalid
- **Decryption errors**: When wrong key is provided or fragments are corrupted
- **Restoration errors**: When fragments are corrupted or manifest doesn't match
- **Permission errors**: When output directory cannot be created

## Examples Workflow
Expand All @@ -137,13 +125,13 @@ The CLI provides clear error messages for common issues:
# photo1.jpg photo2.png document.pdf
```

2. **Fragment and encrypt:**
2. **Fragment images:**
```bash
image-shield encrypt images/photo1.jpg images/photo2.png -o ./backup -k "myPassword123" --restore-filename
image-shield encrypt images/photo1.jpg images/photo2.png -o ./backup --restore-filename
```
```
🔐 Starting image encryption...
✅ Images encrypted successfully to: /path/to/backup
🔀 Starting image fragmentation...
✅ Images fragmented successfully to: /path/to/backup
```

3. **Check output:**
Expand All @@ -154,10 +142,10 @@ The CLI provides clear error messages for common issues:

4. **Restore images:**
```bash
image-shield decrypt backup/*.png -m backup/manifest.json -o ./restored -k "myPassword123"
image-shield decrypt backup/*.png -m backup/manifest.json -o ./restored
```
```
🔓 Starting image decryption...
🔀 Starting image restoration...
✅ Images restored successfully to: /path/to/restored
```

Expand All @@ -169,13 +157,12 @@ The CLI provides clear error messages for common issues:

### Advanced Configuration Example

For maximum security and custom fragmentation:
For custom fragmentation:

```bash
# Encrypt with custom settings
# Fragment with custom settings
image-shield encrypt sensitive/*.jpg \
-o ./vault \
-k "$(openssl rand -hex 32)" \
-b 5 \
-p "secure_chunk" \
-s 42 \
Expand All @@ -193,14 +180,12 @@ image-shield encrypt sensitive/*.jpg \

# Backup script
IMAGES_DIR="./photos"
BACKUP_DIR="./encrypted_backup"
SECRET_KEY="your-secret-key"
BACKUP_DIR="./backup"

# Create backup
echo "Creating encrypted backup..."
echo "Creating backup..."
image-shield encrypt "$IMAGES_DIR"/*.{jpg,png} \
-o "$BACKUP_DIR" \
-k "$SECRET_KEY" \
--restore-filename

if [ $? -eq 0 ]; then
Expand All @@ -218,16 +203,14 @@ fi
#!/bin/bash

# Recovery script
BACKUP_DIR="./encrypted_backup"
BACKUP_DIR="./backup"
RESTORE_DIR="./recovered_photos"
SECRET_KEY="your-secret-key"

# Restore from backup
echo "Restoring from encrypted backup..."
echo "Restoring from backup..."
image-shield decrypt "$BACKUP_DIR"/fragment_*.png \
-m "$BACKUP_DIR/manifest.json" \
-o "$RESTORE_DIR" \
-k "$SECRET_KEY"
-o "$RESTORE_DIR"

if [ $? -eq 0 ]; then
echo "✅ Recovery completed successfully"
Expand Down
6 changes: 2 additions & 4 deletions packages/cli/src/commands/decrypt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ export function registerDecryptCommand(program: Command): void {
.argument("<fragments...>", "Fragment file paths")
.requiredOption("-m, --manifest <path>", "Manifest file path")
.requiredOption("-o, --output <dir>", "Output directory")
.option("-k, --key <key>", "Secret key for decryption")
.action(handleDecryptCommand);
}

Expand All @@ -32,7 +31,7 @@ async function handleDecryptCommand(
options: DecryptOptions,
): Promise<void> {
try {
console.log("🔓 Starting image decryption...");
console.log("🔀 Starting image restoration...");

const imagePaths = validateImagePaths(fragments);
const manifestPath = validateManifestPath(options.manifest);
Expand All @@ -42,13 +41,12 @@ async function handleDecryptCommand(
imagePaths,
manifestPath,
outputDir,
secretKey: options.key,
});

console.log(`✅ Images restored successfully to: ${outputDir}`);
} catch (error) {
console.error(
`❌ Decryption failed: ${error instanceof Error ? error.message : String(error)}`,
`❌ Restoration failed: ${error instanceof Error ? error.message : String(error)}`,
);
process.exit(1);
}
Expand Down
Loading
Loading