You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python本地存储技术问询:无外部数据库的密码vault开发方案

实现本地离线密码管理器的可行方案

Got it, building a local-only password vault that works offline is totally doable—let’s walk through the most practical approaches, with a focus on security since we’re dealing with sensitive data.

核心方案:使用 localStorage 快速落地

localStorage is perfect for this use case because it’s:

  • Persistent: Data stays saved even after the browser closes (until the user clears their browser data)
  • Offline-first: No external database needed—all data lives directly in the user’s browser
  • Easy to use: Has a simple key-value API that’s straightforward to wrap into your app’s logic

关键前提:必须加密敏感数据

Important: localStorage stores data as plaintext in the user’s browser. If you skip encryption, anyone with access to the user’s device (or browser dev tools) can read their passwords. Don’t cut this corner.

Here’s a simplified example using the browser’s built-in Web Crypto API to encrypt/decrypt your password entries:

First, create functions to derive a secure key from the user’s master password (never store the master password itself):

async function deriveKey(masterPassword) {
  const encoder = new TextEncoder();
  const passwordBytes = encoder.encode(masterPassword);
  const salt = encoder.encode("your-unique-salt-here"); // Use a fixed salt or generate one per user
  return window.crypto.subtle.deriveKey(
    { name: "PBKDF2", salt, iterations: 100000, hash: "SHA-256" },
    await window.crypto.subtle.importKey(
      "raw", passwordBytes, { name: "PBKDF2" }, false, ["deriveKey"]
    ),
    { name: "AES-GCM", length: 256 },
    true, ["encrypt", "decrypt"]
  );
}

Then, wrap encryption/decryption logic for your password entries:

async function encryptData(data, key) {
  const encoder = new TextEncoder();
  const dataBytes = encoder.encode(JSON.stringify(data));
  const iv = window.crypto.getRandomValues(new Uint8Array(12));
  const encrypted = await window.crypto.subtle.encrypt(
    { name: "AES-GCM", iv }, key, dataBytes
  );
  return { iv: Array.from(iv), data: Array.from(new Uint8Array(encrypted)) };
}

async function decryptData(encryptedData, key) {
  const iv = new Uint8Array(encryptedData.iv);
  const data = new Uint8Array(encryptedData.data);
  const decrypted = await window.crypto.subtle.decrypt(
    { name: "AES-GCM", iv }, key, data
  );
  return JSON.parse(new TextDecoder().decode(decrypted));
}

封装存储操作

Now, create helper functions to interact with localStorage, combining encryption:

// Save a password entry
async function savePasswordEntry(entry, masterPassword) {
  const key = await deriveKey(masterPassword);
  const encryptedEntry = await encryptData(entry, key);
  localStorage.setItem(`password-${entry.id}`, JSON.stringify(encryptedEntry));
}

// Get all password entries
async function getAllPasswordEntries(masterPassword) {
  const key = await deriveKey(masterPassword);
  const entries = [];
  for (let i = 0; i < localStorage.length; i++) {
    const keyName = localStorage.key(i);
    if (keyName.startsWith("password-")) {
      const encryptedEntry = JSON.parse(localStorage.getItem(keyName));
      const entry = await decryptData(encryptedEntry, key);
      entries.push(entry);
    }
  }
  return entries;
}

备选方案:进阶本地存储选项

If you need to handle larger datasets or more complex queries, consider these alternatives:

  • IndexedDB: Better for storing hundreds/thousands of entries, supports querying and transactions. Great if your app might grow beyond simple key-value storage.
  • File System Access API: Let users export their encrypted password vault as a file (and import it back later). This adds a backup layer so users don’t lose data if they clear their browser.

Critical Security & Usability Notes

  • Never store the master password: Derive the encryption key from it instead, as shown above.
  • Handle private browsing mode: localStorage is disabled in some private/incognito modes—add fallback logic (like temporary in-memory storage) or show a warning to users.
  • Backup reminders: Prompt users regularly to export their encrypted vault, since browser data can be cleared accidentally.
  • Use HTTPS: Even though it’s local, if you host your app online, HTTPS ensures the Web Crypto API works (some browsers restrict it on HTTP).

内容的提问来源于stack exchange,提问作者Mwangi Njuguna

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:19:49