前言WebCrypto API 提供原生的加密能力。本文通过 AES-GCM 与口令派生实现文件加密,并演示密钥的安全持久化与加载流程。能力检测const supportsWebCrypto = !!(crypto && crypto.subtle);

口令派生与生成密钥async function deriveAesKeyFromPassphrase(passphrase, salt) {

const enc = new TextEncoder();

const baseKey = await crypto.subtle.importKey('raw', enc.encode(passphrase), 'PBKDF2', false, ['deriveKey']);

const key = await crypto.subtle.deriveKey({ name: 'PBKDF2', hash: 'SHA-256', salt: enc.encode(salt), iterations: 100000 }, baseKey, { name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']);

return key;

}

async function generateAesKey() {

return crypto.subtle.generateKey({ name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt']);

}

加密与解密async function encryptBytes(key, bytes) {

const iv = crypto.getRandomValues(new Uint8Array(12));

const buf = await crypto.subtle.encrypt({ name: 'AES-GCM', iv }, key, bytes);

return { iv, cipher: new Uint8Array(buf) };

}

async function decryptBytes(key, iv, cipher) {

const buf = await crypto.subtle.decrypt({ name: 'AES-GCM', iv }, key, cipher);

return new Uint8Array(buf);

}

密钥导出与持久化async function exportRawKey(key) {

const raw = await crypto.subtle.exportKey('raw', key);

return new Uint8Array(raw);

}

async function importRawKey(raw) {

return crypto.subtle.importKey('raw', raw, { name: 'AES-GCM' }, true, ['encrypt', 'decrypt']);

}

将密钥与元数据写入 IndexedDB:function openDB(name) {

return new Promise((resolve, reject) => {

const req = indexedDB.open(name, 1);

req.onupgradeneeded = () => {

const db = req.result;

if (!db.objectStoreNames.contains('keys')) db.createObjectStore('keys', { keyPath: 'id' });

};

req.onsuccess = () => resolve(req.result);

req.onerror = () => reject(req.error);

});

}

async function saveKey(id, raw) {

const db = await openDB('crypto');

const tx = db.transaction('keys', 'readwrite');

tx.objectStore('keys').put({ id, raw });

await new Promise((resolve, reject) => { tx.oncomplete = resolve; tx.onerror = () => reject(tx.error); });

db.close();

}

async function loadKey(id) {

const db = await openDB('crypto');

const tx = db.transaction('keys', 'readonly');

const req = tx.objectStore('keys').get(id);

const rec = await new Promise((resolve, reject) => { req.onsuccess = () => resolve(req.result); req.onerror = () => reject(req.error); });

db.close();

return rec ? importRawKey(new Uint8Array(rec.raw)) : null;

}

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部