PCH-02-005-legacy-pbkdf2-doc.patch.md

4.3 KB · raw

rendered · source

1# PCH-02-005 — Document the legacy PBKDF2 import KDF + recommend re-export23**Severity:** Informational4**Target files:** `src/shared/backup.ts:146` (`derivePeachExportKey`),5`src/popup/views/Import.tsx` (re-export notice)6**Report:** peach-code-review.md, Finding PCH-02-00578## Correction to the fix brief910The brief's comment text says "100,000 iterations". The code (and the report)11say **250,000** (`backup.ts:166`). The comment below uses the value the code12actually enforces — a comment that misstates its own parameters is worse than13no comment.1415## Edit 1 — KDF comment at backup.ts:1461617```typescript18// BEFORE (backup.ts:146-150)19export async function derivePeachExportKey(20  password: string,21  salt: Uint8Array,22  opts: { raw?: boolean } = {}23): Promise<Uint8Array> {2425// AFTER26/**27 * LEGACY IMPORT KDF (PCH-02-005):28 * This path derives with PBKDF2-SHA256 (250,000 iterations) for backwards29 * compatibility with `.json` exports sealed before the Argon2id migration —30 * the encrypted-JSON export UI was removed in v2.5.0 (see header), so this31 * KDF is import-only (plus the test fixture generator above).32 *33 * PBKDF2 has no memory-hardness and is materially weaker than the current34 * Argon2id envelope (m=64 MiB, t=3, p=4 — peachPayload.ts) against GPU/ASIC35 * attackers at equal wall-clock cost. Do NOT use this helper for any new36 * format. Users importing an old `.json` backup are prompted to export a37 * fresh backup afterwards (Import.tsx legacy-KDF notice).38 */39export async function derivePeachExportKey(40  password: string,41  salt: Uint8Array,42  opts: { raw?: boolean } = {}43): Promise<Uint8Array> {44```4546(The existing LV-1 NFC comment inside the function body stays as is.)4748## Edit 2 — post-import re-export notice in Import.tsx4950Verified: there is currently **no** user-facing recommendation after a51successful PBKDF2 (`peach-json`) import. The import success path keeps the52view mounted and already surfaces a post-import `duplicateWarning` notice53(Import.tsx:790) — the legacy-KDF notice mirrors that exact mechanism.54552a. Add a signal next to `duplicateWarning` (Import.tsx:~425):5657```typescript58// AFTER the existing line:59  const [duplicateWarning, setDuplicateWarning] = createSignal<number>(0);60// ADD:61  // PCH-02-005: set when a legacy PBKDF2-encrypted `.json` backup imports62  // successfully — prompts the user to re-export under the Argon2id format.63  const [legacyKdfNotice, setLegacyKdfNotice] = createSignal(false);64```65662b. In `handleImport`, alongside `setDuplicateWarning(dupes)` (the67success tail, Import.tsx:~604):6869```typescript70// BEFORE71      setDuplicateWarning(dupes);72      await props.onImport();7374// AFTER75      setDuplicateWarning(dupes);76      // PCH-02-005: "peach-json" is the legacy PBKDF2-SHA256 envelope; every77      // other recognised format is plaintext-source (no KDF) or current-format.78      setLegacyKdfNotice(currentPreview.format === "peach-json");79      await props.onImport();80```8182Also reset it where the other notices reset (`handleFileSelect`, alongside83`setError(null)` / `setAwaitingReplaceConfirm(false)`):8485```typescript86      setLegacyKdfNotice(false);87```88892c. Render next to the duplicate-warning block (Import.tsx:~790, same90`<Show>` pattern and styling class as the sibling notice):9192```tsx93        <Show when={legacyKdfNotice() && !importing()}>94          <div class="peach-settings-group">95            <div class="peach-restore-warning">96              This backup was created with Peach's older encryption format97              (PBKDF2). It imported fine — but we recommend exporting a fresh98              backup now so your paper/file backups use the current, stronger99              format.100            </div>101          </div>102        </Show>103```104105(Class choice: `peach-restore-warning` is the existing soft-warning surface106used three blocks above; no new CSS.)107108## Tests109110UI-notice coverage belongs in `src/popup/views/contracts.test.tsx` style; the111notice is a pure render-state change. Suggested single contract case (optional,112not counted as a security regression test): mock `parseImportSource` to return113`format: "peach-json"`, drive `handleImport`, assert the notice text renders.114The KDF comment itself needs no test.115116## Save message (integration)117118`fix: PCH-02-005 document legacy PBKDF2 import path + recommend re-export after legacy import`