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
- Open the relay page via https:// or http://localhost
- Serve the relay behind a TLS-terminating proxy
- 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.