One Calendar is a privacy-first calendar web app built with Next.js. It has modern security features, including e2ee, password-protected sharing, and self-destructing share links 📅 calendar.xyehr.cn
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

Delete lib/crypto.ts

authored by

Evan Huang and committed by
GitHub
f0db2df3 f9da62e2

-91
-91
lib/crypto.ts
··· 1 - // 从密码派生密钥 2 - async function deriveKey(password: string, salt?: Uint8Array): Promise<{ key: CryptoKey; salt: Uint8Array }> { 3 - // 如果没有提供盐值,则生成一个新的 4 - if (!salt) { 5 - salt = crypto.getRandomValues(new Uint8Array(16)) 6 - } 7 - 8 - // 从密码派生密钥 9 - const keyMaterial = await crypto.subtle.importKey( 10 - "raw", 11 - new TextEncoder().encode(password), 12 - { name: "PBKDF2" }, 13 - false, 14 - ["deriveBits", "deriveKey"], 15 - ) 16 - 17 - const key = await crypto.subtle.deriveKey( 18 - { 19 - name: "PBKDF2", 20 - salt, 21 - iterations: 100000, 22 - hash: "SHA-256", 23 - }, 24 - keyMaterial, 25 - { name: "AES-GCM", length: 256 }, 26 - false, 27 - ["encrypt", "decrypt"], 28 - ) 29 - 30 - return { key, salt } 31 - } 32 - 33 - // 加密数据 34 - export async function encrypt(data: string, password: string): Promise<string> { 35 - // 生成初始化向量 36 - const iv = crypto.getRandomValues(new Uint8Array(12)) 37 - 38 - // 从密码派生密钥 39 - const { key, salt } = await deriveKey(password) 40 - 41 - // 加密数据 42 - const encryptedData = await crypto.subtle.encrypt( 43 - { 44 - name: "AES-GCM", 45 - iv, 46 - }, 47 - key, 48 - new TextEncoder().encode(data), 49 - ) 50 - 51 - // 将加密数据、盐值和初始化向量合并为一个数组 52 - const result = new Uint8Array(salt.length + iv.length + encryptedData.byteLength) 53 - result.set(salt, 0) 54 - result.set(iv, salt.length) 55 - result.set(new Uint8Array(encryptedData), salt.length + iv.length) 56 - 57 - // 将结果转换为Base64字符串 58 - return btoa(String.fromCharCode(...result)) 59 - } 60 - 61 - // 解密数据 62 - export async function decrypt(encryptedData: string, password: string): Promise<string> { 63 - // 将Base64字符串转换回Uint8Array 64 - const data = new Uint8Array( 65 - atob(encryptedData) 66 - .split("") 67 - .map((char) => char.charCodeAt(0)), 68 - ) 69 - 70 - // 提取盐值、初始化向量和加密数据 71 - const salt = data.slice(0, 16) 72 - const iv = data.slice(16, 28) 73 - const ciphertext = data.slice(28) 74 - 75 - // 从密码和盐值派生密钥 76 - const { key } = await deriveKey(password, salt) 77 - 78 - // 解密数据 79 - const decryptedData = await crypto.subtle.decrypt( 80 - { 81 - name: "AES-GCM", 82 - iv, 83 - }, 84 - key, 85 - ciphertext, 86 - ) 87 - 88 - // 将解密后的数据转换为字符串 89 - return new TextDecoder().decode(decryptedData) 90 - } 91 -