加载中...

OleanderChat

端到端加密的跨平台聊天解决方案

产品概述

安全通讯新标准

OleanderChat 是 OleanderStudio 推出的旗舰产品,基于 Kotlin Multiplatform 和 Compose Multiplatform 构建的跨平台聊天应用。采用 RSA-2048 + AES-256-GCM 混合加密方案,确保您的每一次对话都安全无忧。后端可自托管到 Cloudflare Workers,完全掌控数据。

支持 Android 和桌面端(JVM),一套代码,多端运行。

获取源码

核心功能

OleanderChat 提供完整的即时通讯解决方案,从加密到文件分享,一应俱全。

端到端加密

RSA-2048 + AES-256-GCM 混合加密,每条消息独立加密,私钥仅存储在本地。

实时消息

基于 WebSocket 连接的即时通讯,消息实时送达,支持未读消息徽章。可部署到自己的 Cloudflare Worker。

好友系统

使用 UUID 添加好友,发送和接受好友请求,管理您的好友列表。

文件分享

通过 EasySend 集成上传和分享文件,文件元数据加密传输,双方均可解密。

消息持久化

聊天记录本地保存,跨会话保留,长按即可删除聊天记录。

跨平台支持

支持 Android 和桌面端(JVM),基于 Material Design 3 的现代化 UI。

安全架构

加密原理

1. 密钥生成

首次启动时,每个用户都会获得唯一的 RSA 密钥对(公钥 + 私钥)。

2. 密钥交换

发送消息或好友请求时自动交换公钥,私钥永远不会传输到服务器。

3. 消息加密

每条消息生成随机 AES-256 密钥,使用 AES-256-GCM 加密内容,再用接收方 RSA 公钥加密 AES 密钥。

4. 安全解密

只有预期接收方才能使用私钥解密消息,确保端到端的安全性。

技术

OleanderChat 采用现代化的技术架构,确保性能和体验。

Kotlin Multiplatform

跨平台共享业务逻辑

Compose Multiplatform

声明式 UI 框架

WebSocket

实时通讯连接

RSA + AES

混合加密方案

后端部署

自托管 WebSocket 服务器

OleanderChat 的后端基于 Cloudflare Workers 构建,使用 Durable Objects 实现 WebSocket 消息路由。您可以免费部署到自己的 Cloudflare 账户,完全掌控数据。

轻量级设计

单文件 Worker 脚本,无需数据库,UUID 即身份标识。

免费部署

Cloudflare Workers 免费额度足以支撑个人和小团队使用。

隐私优先

消息仅作为传输中继,不存储在服务器端,端到端加密确保内容安全。

查看部署指南

快速开始

只需几步即可部署和运行 OleanderChat。

1. 部署后端

将 Cloudflare Worker 脚本部署到您的账户,获取 WebSocket 地址。

2. 克隆仓库

从 GitHub 克隆 OleanderChat 客户端源码到本地。

3. 配置运行

配置 WebSocket 地址,使用 Gradle 运行 Android 或桌面端应用。

4. 添加好友

分享您的 UUID,添加好友,开始端到端加密聊天。

后端源码

以下是可以直接部署到 Cloudflare Workers 的完整后端代码。

import { DurableObject } from "cloudflare:workers";

class UUIDRouter extends DurableObject {
  constructor(ctx, env) {
    super(ctx, env);
    this.ctx.setWebSocketAutoResponse(
      new WebSocketRequestResponsePair("ping", "pong")
    );
  }

  async fetch(request) {
    const url = new URL(request.url);
    const clientUUID = url.searchParams.get("uuid");
    const pair = new WebSocketPair();
    const [client, server] = Object.values(pair);
    this.ctx.acceptWebSocket(server, [clientUUID]);
    server.serializeAttachment({ uuid: clientUUID });
    return new Response(null, { status: 101, webSocket: client });
  }

  async webSocketMessage(ws, message) {
    const senderAtt = ws.deserializeAttachment();
    const senderUUID = senderAtt?.uuid;
    let msg;
    try {
      msg = JSON.parse(message);
    } catch {
      ws.send(JSON.stringify({ error: "Invalid JSON" }));
      return;
    }
    const targetUUID = msg.UUID接收;
    const payload = msg.message;
    if (!targetUUID) {
      ws.send(JSON.stringify({ error: "Missing UUID接收" }));
      return;
    }
    const out = JSON.stringify({ [senderUUID]: payload });
    const target = this.ctx.getWebSockets(targetUUID)
      .find((w) => w.deserializeAttachment()?.uuid === targetUUID);
    if (target) {
      target.send(out);
    } else {
      ws.send(JSON.stringify({ error: `UUID ${targetUUID} not online` }));
    }
  }

  async webSocketClose(ws, code, reason, wasClean) {
    ws.close(code, reason);
  }

  async webSocketError(ws, error) {
    console.error("ws error", error);
  }
}

export default {
  async fetch(request, env, ctx) {
    const url = new URL(request.url);
    if (url.pathname !== "/ws") {
      return new Response("Supported endpoints: /ws?uuid=xxx", { status: 200 });
    }
    if (request.headers.get("Upgrade") !== "websocket") {
      return new Response("Expected Upgrade: websocket", { status: 426 });
    }
    const uuid = url.searchParams.get("uuid");
    if (!uuid) {
      return new Response("Missing uuid query param", { status: 400 });
    }
    const id = env.UUID_ROUTER.idFromName("global-router");
    const stub = env.UUID_ROUTER.get(id);
    return stub.fetch(request);
  }
};

部署步骤:

  1. 登录 Cloudflare 控制台,创建一个新的 Worker
  2. 创建 Durable Object 绑定,变量名设为 UUID_ROUTER
  3. 将上述代码粘贴到 Worker 编辑器中
  4. 部署后即可通过 wss://your-worker.your-subdomain.workers.dev/ws?uuid=YOUR_UUID 连接
准备好开始了吗?

立即体验 OleanderChat

开源、免费、安全。部署自己的后端,完全掌控数据。

GitHub 仓库