---
title: "FiSH — Mango 3.1 Grove-Erweiterung"
description: "Kompatibilität mit dem älteren FiSH-Verfahren mit statischen Schlüsseln. Kanal- und Query-Schlüssel werden pro Netzwerk im Schlüsselbund gespeichert."
url: "https://mangoirc.chat/de/extensions/fish"
language: "de"
---

[← Alle Erweiterungen](https://mangoirc.chat/de/extensions)

Interoperabilität · Root

# FiSH

von [Mango](https://mangoirc.chat/)

Kompatibilität mit dem älteren FiSH-Verfahren mit statischen Schlüsseln. Kanal- und Query-Schlüssel werden pro Netzwerk im Schlüsselbund gespeichert.

In Mango 3.1 installieren 29 KB · Mango 3.1

Version

0.1.5

Ausführungsart

Serverweiter Root

Grove API

1

Aktualisiert

2026-09-12

Angeforderte Zugriffsrechte

## 5 Berechtigungen

- **Schrägstrich-Befehle hinzufügen**Registriert eigene Befehle und kann native Befehlsergebnis-Karten anzeigen.
- **Empfangene Nachrichten filtern**Kann eingehende Nachrichtentexte vor der Anzeige durch Mango umwandeln oder ausblenden.
- **Gesendete Nachrichten filtern**Kann ausgehende Nachrichtentexte vor dem Erreichen von IRC umwandeln oder blockieren.
- **Lokale Daten behalten**Speichert Erweiterungsdaten auf diesem Gerät in einem eigenen isolierten Bereich.
- **Geheimnisse im Schlüsselbund behalten**Speichert private Werte in einem Keychain-Namensraum, der für diese Erweiterung reserviert ist.

Netzwerkzugriff

## Kein Internetzugriff

Sein Manifest deklariert keine externen Hosts. Groves Sandbox blockiert Netzwerkanfragen außerhalb des Pakets.

Aus der Erweiterung

## README · Englisch

# FiSH — a Grove Root

This headless example adds basic static-key FiSH interoperability to Mango without putting legacy crypto policy in the IRC engine.

Supported in this first phase:

- outbound CBC messages using the ` +OK * ` prefix;
- inbound CBC ` +OK * ` / ` mcps * `;
- inbound legacy ECB ` +OK  ` / ` mcps  `;
- per-network, per-target static keys stored in Keychain;
- separate ciphertext wire text and plaintext optimistic display text;
- a compact host-rendered fish symbol (` FISH ` text fallback on older Mango);
- fail-closed outbound encryption: if a configured target cannot be encrypted, Mango sends nothing and shows the safe filter error.

DH1080 key exchange, encrypted topics, and ACTION (` /me `) encryption remain out of scope.

## Security warning

FiSH is legacy unauthenticated encryption. It does not provide peer authentication, forward secrecy, replay protection, or MITM protection. ECB is especially weak and deterministic. The Root prefers CBC for newly sent messages, but CBC still is not authenticated encryption.

Use TLS and prefer a modern protocol whenever both endpoints support one.

FiSH uses Mango’s native Markdown card rendering for command examples, configured-target lists, and encryption status. Every card retains its required plain-text body for Copy and as a fallback on older Mango versions.

## Commands

Run these in the channel or query whose key you want to manage:

```text
/fish setkey <key>
/fish delkey
/fish status
/fish list
```

` list ` and ` status ` never reveal key values. The persistent WebKit store keeps only target names and opaque Keychain references; the ` storage.secure ` capability namespaces actual values by this Root’s id and Mango’s opaque network id. Target identity comes only from Mango’s host-canonical ` CASEMAPPING ` key, so key management intentionally operates on the currently open channel or query. Key values may contain spaces.

The outbound filter registers before Keychain loading begins, so a target already present in the persistent index fails closed during startup and never gets a brief plaintext-send window. The inbound filter registers after saved keys finish loading; Mango then replays the visible transcript through it, so restored ciphertext is decrypted without stopping and restarting the Root. Setting a new key re-registers the ready filter after the Keychain write, which immediately replays and decrypts already-loaded messages in the current buffer. Deleting a key performs the same replay so those rows return to ciphertext.

Development builds that stored an explicit target without a canonical key keep that record visible in ` list `. The first message or key command in a target with the exact same server spelling rebinds it to Mango’s host-canonical key; the Root never guesses with locale-dependent lowercasing.

## Implementation notes

- Since FiSH 0.1.4, encryption and decryption are self-contained and run in bundled JavaScript code. It no longer calls ` grove.crypto.blowfish `; Mango still provides general message filters, cards, and Keychain storage.
- The Root owns FiSH markers, zero padding, random CBC prefix, standard CBC base64, and the unusual ECB base64 layout.
- Blowfish blocks use the bundled MIT-licensed [egoroof/blowfish 4.0.3](https://github.com/egoroof/blowfish/tree/v4.0.3) implementation. No crypto code is downloaded at runtime. See ` crypto/vendor/README.md ` for provenance and reproducible bundling.
- Existing key behavior is preserved byte-for-byte, including Mango’s legacy expansion of 1–7-byte keys to exactly eight bytes. For 3/5/6/7-byte keys this differs from standard Blowfish key cycling; use keys of at least eight UTF-8 bytes for interoperability with other clients. This release deliberately does not silently migrate existing keys or invalidate saved ciphertext.
- The ECB/CBC compatibility tests use published vectors from the MIT-licensed [` whiym/fish `](https://github.com/whiym/fish) implementation.

Run the standalone wire-codec checks with:

```sh
node crypto/fish-codec.test.cjs
node crypto/fish-blowfish.test.cjs
node fish-root.test.cjs
```

On macOS, ` node crypto/fish-blowfish.test.cjs --native ` additionally compares all 1–56-byte key lengths against Mango’s existing CommonCrypto implementation. The compiler/oracle is test-only and is not included in the ` .grove ` package.

**manifest.json**app.mango.grove.fish

```
{
  "grove": 1,
  "id": "app.mango.grove.fish",
  "name": "FiSH",
  "version": "0.1.5",
  "description": "Legacy FiSH static-key interoperability using Keychain-backed per-network channel and query keys.",
  "author": {
    "name": "Mango",
    "url": "https://mangoirc.chat"
  },
  "readme": "README.md",
  "entry": "index.html",
  "presentation": {
    "surfaces": [
      "headless"
    ],
    "scope": "server"
  },
  "capabilities": [
    "commands.register",
    "messages.filter.inbound",
    "messages.filter.outbound",
    "storage",
    "storage.secure"
  ],
  "hostPermissions": []
}
```
