BigPizzaV3/CodexPlusPlus · error · Error

当前页面不是安全上下文,WebCrypto 不可用

Error message

当前页面不是安全上下文,WebCrypto 不可用

What it means

Client-side error in the mobile relay web page (mobile_relay_page): the page is not in a secure context (not HTTPS/localhost), so crypto.subtle is unavailable and the AES-GCM key for relay communication cannot be derived. Fired by the browser's WebCrypto secure-context restriction.

Source

Thrown at apps/codex-plus-mobile-relay/src/main.rs:792

const params = new URLSearchParams(location.search);
const statusEl = $("status");
const sessionsEl = $("sessions");
const messagesEl = $("messages");
const titleEl = $("threadTitle");
const metaEl = $("threadMeta");
const sessionsPane = $("sessionsPane");
const detailPane = $("detailPane");
function setStatus(text, error = false) { statusEl.textContent = text; statusEl.classList.toggle("error", error); }
function b64url(bytes) {
  let text = btoa(String.fromCharCode(...new Uint8Array(bytes)));
  return text.replaceAll("+", "-").replaceAll("/", "_").replace(/=+$/g, "");
}
function b64urlDecode(text) {
  const padded = text.replaceAll("-", "+").replaceAll("_", "/") + "===".slice((text.length + 3) % 4);
  return Uint8Array.from(atob(padded), ch => ch.charCodeAt(0));
}
async function cryptoKey() {
  if (!crypto?.subtle) throw new Error("当前页面不是安全上下文,WebCrypto 不可用");
  const raw = new TextEncoder().encode($("key").value);
  const digest = await crypto.subtle.digest("SHA-256", raw);
  return crypto.subtle.importKey("raw", digest, "AES-GCM", false, ["encrypt", "decrypt"]);
}
async function encrypt(payload) {
  if (!crypto?.subtle) {
    setStatus("当前浏览器禁用 WebCrypto,已使用兼容模式", true);
    return { type: "plaintext", payload };
  }
  const key = await cryptoKey();
  const nonce = crypto.getRandomValues(new Uint8Array(12));
  const plain = new TextEncoder().encode(JSON.stringify(payload));
  const encrypted = await crypto.subtle.encrypt({ name: "AES-GCM", iv: nonce }, key, plain);
  return { type: "encrypted", nonce: b64url(nonce), payload: b64url(encrypted) };
}
async function decrypt(envelope) {
  if (envelope?.type === "plaintext") return envelope.payload;
  if (!envelope || envelope.type !== "encrypted") throw new Error("收到未加密数据包");

View on GitHub (pinned to f2074595a2)

Solutions

  1. Open the relay page via https:// or http://localhost
  2. Serve the relay behind a TLS-terminating proxy
  3. Use a browser permitting WebCrypto on the origin
Defensive patterns

Strategy: try-catch

When it happens

Trigger: Thrown at apps/codex-plus-mobile-relay/src/main.rs:792 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@f2074595a2 (2026-08-23). Data as JSON: /api/errors/d3820275e79838c1. Report an issue: GitHub.