WebCrypto API实战:前端加密与安全通信完全指南

WebCrypto API简介 WebCrypto API是现代浏览器提供的原生加密API,提供了安全的加密操作能力。与第三方库相比,它有以下优势: 浏览器原生支持,无需额外依赖 使用系统级加密库,性能更优 安全的密钥管理,密钥不暴露给JavaScript 同步和异步API支持 对称加密(AES) 生成密钥 1 2 3 4 5 6 7 8 9 10 11 12 // 生成AES密钥 async function generateAesKey() { const key = await crypto.subtle.generateKey( { name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt'] ) return key } 加密数据 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 async function encryptData(data, key) { const encoder = new TextEncoder() const iv = crypto.getRandomValues(new Uint8Array(12)) const encrypted = await crypto.subtle.encrypt( { name: 'AES-GCM', iv: iv }, key, encoder.encode(data) ) return { ciphertext: new Uint8Array(encrypted), iv: iv } } 解密数据 1 2 3 4 5 6 7 8 9 10 11 12 13 async function decryptData(encryptedData, key, iv) { const decrypted = await crypto.subtle.decrypt( { name: 'AES-GCM', iv: iv }, key, encryptedData ) const decoder = new TextDecoder() return decoder.decode(decrypted) } 非对称加密(RSA) 生成密钥对 1 2 3 4 5 6 7 8 9 10 11 12 13 14 async function generateRsaKeyPair() { const keyPair = await crypto.subtle.generateKey( { name: 'RSA-OAEP', modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: 'SHA-256' }, true, ['encrypt', 'decrypt'] ) return keyPair } 导出和导入密钥 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 // 导出公钥 async function exportPublicKey(key) { const exported = await crypto.subtle.exportKey( 'spki', key ) return new Uint8Array(exported) } // 导入公钥 async function importPublicKey(keyData) { return await crypto.subtle.importKey( 'spki', keyData, { name: 'RSA-OAEP', hash: 'SHA-256' }, true, ['encrypt'] ) } 哈希算法 计算哈希 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 async function hashData(data, algorithm = 'SHA-256') { const encoder = new TextEncoder() const dataBuffer = encoder.encode(data) const hashBuffer = await crypto.subtle.digest( algorithm, dataBuffer ) const hashArray = Array.from(new Uint8Array(hashBuffer)) return hashArray.map(b => b.toString(16).padStart(2, '0')).join('') } // 使用 const hash = await hashData('Hello, WebCrypto!', 'SHA-256') console.log(hash) // 64位十六进制字符串 HMAC 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 async function hmac(key, message) { const encoder = new TextEncoder() const cryptoKey = await crypto.subtle.importKey( 'raw', encoder.encode(key), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign'] ) const signature = await crypto.subtle.sign( 'HMAC', cryptoKey, encoder.encode(message) ) const hashArray = Array.from(new Uint8Array(signature)) return hashArray.map(b => b.toString(16).padStart(2, '0')).join('') } 数字签名 生成签名 1 2 3 4 5 6 7 8 9 10 11 12 13 14 async function signData(data, privateKey) { const encoder = new TextEncoder() const signature = await crypto.subtle.sign( { name: 'RSA-PSS', saltLength: 32 }, privateKey, encoder.encode(data) ) return new Uint8Array(signature) } 验证签名 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 async function verifySignature(data, signature, publicKey) { const encoder = new TextEncoder() const result = await crypto.subtle.verify( { name: 'RSA-PSS', saltLength: 32 }, publicKey, signature, encoder.encode(data) ) return result } 密钥派生(PBKDF2) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 async function deriveKey(password, salt) { const encoder = new TextEncoder() const keyMaterial = await crypto.subtle.importKey( 'raw', encoder.encode(password), 'PBKDF2', false, ['deriveKey'] ) const key = await crypto.subtle.deriveKey( { name: 'PBKDF2', salt: encoder.encode(salt), iterations: 100000, hash: 'SHA-256' }, keyMaterial, { name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt'] ) return key } 实战案例 端到端加密聊天 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 class E2EChat { constructor() { this.keyPair = null this.peerKeys = new Map() } async init() { // 生成密钥对 this.keyPair = await crypto.subtle.generateKey( { name: 'RSA-OAEP', modulusLength: 2048, publicExponent: new Uint8Array([1, 0, 1]), hash: 'SHA-256' }, true, ['encrypt', 'decrypt'] ) } async getPublicKey() { const exported = await crypto.subtle.exportKey('spki', this.keyPair.publicKey) return btoa(String.fromCharCode(...new Uint8Array(exported))) } async addPeer(id, publicKeyData) { const binaryString = atob(publicKeyData) const bytes = new Uint8Array(binaryString.length) for (let i = 0; i < binaryString.length; i++) { bytes[i] = binaryString.charCodeAt(i) } const publicKey = await crypto.subtle.importKey( 'spki', bytes, { name: 'RSA-OAEP', hash: 'SHA-256' }, true, ['encrypt'] ) this.peerKeys.set(id, publicKey) } async sendMessage(peerId, message) { const publicKey = this.peerKeys.get(peerId) if (!publicKey) throw new Error('Peer not found') // 生成会话密钥 const sessionKey = await this.generateSessionKey() // 加密消息 const encryptedMessage = await this.encryptMessage(message, sessionKey) // 加密会话密钥 const encryptedKey = await this.encryptSessionKey(sessionKey, publicKey) return { message: encryptedMessage, key: encryptedKey } } async receiveMessage(data) { // 解密会话密钥 const sessionKey = await this.decryptSessionKey(data.key) // 解密消息 return await this.decryptMessage(data.message, sessionKey) } async generateSessionKey() { return await crypto.subtle.generateKey( { name: 'AES-GCM', length: 256 }, true, ['encrypt', 'decrypt'] ) } async encryptMessage(message, key) { const encoder = new TextEncoder() const iv = crypto.getRandomValues(new Uint8Array(12)) const encrypted = await crypto.subtle.encrypt( { name: 'AES-GCM', iv: iv }, key, encoder.encode(message) ) return { data: btoa(String.fromCharCode(...new Uint8Array(encrypted))), iv: btoa(String.fromCharCode(...iv)) } } async decryptMessage(data, key) { const ciphertext = Uint8Array.from(atob(data.data), c => c.charCodeAt(0)) const iv = Uint8Array.from(atob(data.iv), c => c.charCodeAt(0)) const decrypted = await crypto.subtle.decrypt( { name: 'AES-GCM', iv: iv }, key, ciphertext ) const decoder = new TextDecoder() return decoder.decode(decrypted) } } 安全最佳实践 密钥管理 ...

TypeScript类型体操进阶:掌握高级类型系统

TypeScript类型系统进阶 TypeScript的类型系统非常强大,掌握高级类型特性可以帮助我们写出更安全、更优雅的代码。 条件类型 基础条件类型 1 2 3 4 5 6 7 8 9 10 // 类似三元表达式 type IsString<T> = T extends string ? true : false type Test1 = IsString<string> // true type Test2 = IsString<number> // false // 嵌套条件类型 type NonNullable<T> = T extends null | undefined ? never : T type Test3 = NonNullable<string | null> // string 分布式条件类型 1 2 3 4 5 6 7 8 9 // 联合类型会分布式应用条件类型 type ToArray<T> = T extends any ? T[] : never type Test4 = ToArray<string | number> // string[] | number[] // 阻止分布 type ToArrayNonDistributive<T> = [T] extends [any] ? T[] : never type Test5 = ToArrayNonDistributive<string | number> // (string | number)[] 类型推断 1 2 3 4 5 6 7 8 9 10 // Infer关键字 type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never type Fn = (x: number) => string type Test6 = ReturnType<Fn> // string // 解包Promise type UnwrapPromise<T> = T extends Promise<infer U> ? U : T type Test7 = UnwrapPromise<Promise<string>> // string 映射类型 基础映射类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 // 将所有属性变为可选 type Partial<T> = { [P in keyof T]?: T[P] } // 将所有属性变为必需 type Required<T> = { [P in keyof T]-?: T[P] } // 只读 type Readonly<T> = { readonly [P in keyof T]: T[P] } 高级映射类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // 只保留特定类型 type OnlyStrings<T> = { [P in keyof T as T[P] extends string ? P : never]: T[P] } interface User { name: string age: number email: string } type Test8 = OnlyStrings<User> // { name: string; email: string } // 条件映射 type Getters<T> = { [P in keyof T as `get${Capitalize<string & P>}`]: () => T[P] } type Test9 = Getters<{ name: string; age: number }> // { getName: () => string; getAge: () => number } 模板字面量类型 基础用法 1 2 3 4 type Greeting = `hello ${string}` const test: Greeting = 'hello world' // ✓ const test2: Greeting = 'hi world' // ✗ 高级应用 1 2 3 4 5 6 7 8 9 10 // 事件名称类型 type EventName<T extends string> = `on${Capitalize<T>}` type Test10 = EventName<'click'> // 'onClick' // 路径类型 type Path<T extends string> = `/${T}` | `${Path<T>}/${T}` // 组合类型 type CssValue<T extends number> = `${T}px` | `${T}%` | `${t}em` 递归类型 深度只读 1 2 3 4 5 6 7 8 9 10 11 12 13 type DeepReadonly<T> = { readonly [P in keyof T]: T[P] extends object ? DeepReadonly<T[P]> : T[P] } interface Config { database: { host: string port: number } } type Test11 = DeepReadonly<Config> // 所有嵌套属性都变为只读 深度必需 1 2 3 type DeepRequired<T> = { [P in keyof T]-?: T[P] extends object ? DeepRequired<T[P]> : T[P] } 品牌类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // 创建唯一类型 type Brand<T, B> = T & { __brand: B } type USD = Brand<number, 'USD'> type EUR = Brand<number, 'EUR'> const usd: USD = 100 as USD const eur: EUR = 100 as EUR // 不能直接赋值 // eur = usd // ✗ 类型错误 function addUSD(a: USD, b: USD): USD { return (a + b) as USD } 函数类型高级应用 函数重载 1 2 3 4 5 6 7 8 function process(input: string): string function process(input: number): number function process(input: string | number): string | number { return input } const result1 = process('hello') // string const result2 = process(123) // number 参数类型推断 1 2 3 4 5 6 7 8 9 10 // 元组转函数参数 type TupleToFn<T extends any[]> = T extends [...infer Args, infer R] ? (...args: Args) => R : never type Test12 = TupleToFn<[string, number, boolean]> // 反向推断 type FnToTuple<T extends (...args: any[]) => any> = T extends (...args: infer A) => any ? A : never 类型守卫 typeof守卫 1 2 3 4 5 6 7 8 9 10 function isString(value: unknown): value is string { return typeof value === 'string' } function process(value: unknown) { if (isString(value)) { // 这里value的类型是string console.log(value.toUpperCase()) } } in守卫 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 interface Cat { meow(): void } interface Dog { bark(): void } function makeSound(animal: Cat | Dog) { if ('meow' in animal) { animal.meow() } else { animal.bark() } } instanceof守卫 1 2 3 4 5 6 7 8 9 10 11 12 13 class Error1 extends Error { code = 'ERROR_1' } class Error2 extends Error { code = 'ERROR_2' } function handleError(error: Error) { if (error instanceof Error1) { console.log(error.code) } } 高级工具类型 OmitByType 1 2 3 4 5 6 7 8 9 10 11 12 type OmitByType<T, U> = { [P in keyof T as T[P] extends U ? never : P]: T[P] } interface Test { name: string age: number active: boolean } type Test13 = OmitByType<Test, boolean> // { name: string; age: number } DeepPick 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 type DeepPick<T, K extends string> = K extends `${infer Key}.${infer Rest}` ? Key extends keyof T ? { [P in Key]: DeepPick<T[P], Rest> } : never : K extends keyof T ? { [P in K]: T[K] } : never interface User { profile: { name: string email: string } settings: { theme: string } } type Test14 = DeepPick<User, 'profile.name'> // { profile: { name: string } } 实战案例 表单类型定义 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 type FieldProps<T> = { value: T onChange: (value: T) => void error?: string } type FormFields<T> = { [K in keyof T]: FieldProps<T[K]> } interface LoginData { email: string password: string remember: boolean } type LoginForm = FormFields<LoginData> API响应类型 1 2 3 4 5 6 type ApiResponse<T, E = Error> = | { success: true; data: T } | { success: false; error: E } type UserResponse = ApiResponse<User> type ErrorResponse = ApiResponse<never, NetworkError> 最佳实践 优先使用类型推导 - 让TypeScript自动推导类型 避免使用any - 使用unknown代替 合理使用泛型 - 提高代码复用性 类型守卫 - 缩小类型范围 品牌类型 - 创建语义化类型 总结 TypeScript类型系统非常强大,掌握高级类型特性可以帮助我们构建更安全的代码。 ...

Vue 3.5新特性深度解析:响应式系统的重大升级

引言 Vue 3.5作为Vue 3系列的最新版本,带来了许多令人兴奋的新特性和性能优化。本文将深入分析这些新特性的技术细节,并通过实际代码示例展示如何在项目中应用它们。 核心新特性概览 响应式系统优化 - 内存占用降低,性能提升 Props解构 - 更简洁的API defineModel改进 - 简化双向绑定 Suspense增强 - 更好的异步组件处理 SSR改进 - 服务端渲染性能提升 TypeScript支持 - 更好的类型推导 响应式系统优化 内存优化 Vue 3.5对响应式系统进行了底层重构,显著降低了内存占用: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <script setup> import { ref, reactive, computed } from 'vue' // Vue 3.5: 内存占用优化 const items = ref(new Array(10000).fill(0).map((_, i) => ({ id: i, name: `Item ${i}`, value: Math.random() })) // 计算属性缓存优化 const total = computed(() => { return items.value.reduce((sum, item) => sum + item.value, 0) }) // 响应式Map/Set性能提升 const mapData = reactive(new Map()) const setData = reactive(new Set()) </script> Proxy优化 1 2 3 4 5 6 7 8 9 10 11 12 13 // Vue 3.5的Proxy实现更加高效 const state = reactive({ nested: { deeply: { value: 1 } } }) // 触发追踪优化 watchEffect(() => { console.log(state.nested.deeply.value) // 更少的依赖追踪开销 }) Props解构 基础用法 Vue 3.5中最具实用性的特性之一: ...

WebAssembly在前端工程中的实践:突破JavaScript性能瓶颈

引言 随着Web应用的复杂度不断提升,JavaScript在处理计算密集型任务时逐渐暴露出性能瓶颈。WebAssembly(Wasm)作为一种新型的二进制指令格式,为Web平台带来了接近原生的执行性能。本文将结合实际项目经验,深入探讨WebAssembly在前端工程中的应用实践。 WebAssembly的核心优势 1. 近原生执行性能 WebAssembly采用二进制格式,体积小、解析快,执行速度接近原生代码。以下是性能对比数据(基于斐波那契数列计算): 1 2 3 4 5 6 // JavaScript实现 function fibonacci(n) { return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); } // WebAssembly (Rust编译) 可提升10-50倍性能 2. 多语言支持 开发者可以使用Rust、C++、Go等多种语言编写Wasm模块: 1 2 3 4 5 6 7 8 9 // Rust实现斐波那契 #[wasm_bindgen] pub fn fibonacci(n: u32) -> u32 { match n { 0 => 0, 1 => 1, _ => fibonacci(n - 1) + fibonacci(n - 2), } } 3. 安全隔离 Wasm运行在沙箱环境中,内存隔离确保了安全性。 ...

现代前端开发调试技巧:从Console到DevTools的完整指南

深入探讨现代前端开发中的调试技巧,包括浏览器DevTools高级功能、Source Map配置、断点调试、性能分析和常见问题排查方法。

JavaScript异步编程最佳实践:从回调到async/await

深入探讨JavaScript异步编程的演进历程,掌握Promise和async/await的最佳实践。

Vue 3.5 Composition API 深度解析:掌握响应式编程的艺术

深入探索Vue 3.5 Composition API的核心概念和高级用法,帮助你掌握响应式编程的精髓。

JavaScript异步编程最佳实践:从回调到Async/Await的完整指南

深入探讨JavaScript异步编程的最佳实践,涵盖回调函数、Promise、Async/Await、错误处理、并发控制等关键概念,帮助开发者编写更优雅的异步代码。

Webpack 5现代化前端工具链配置:从零开始构建高性能项目

全面介绍Webpack 5的现代化配置,涵盖模块联邦、持久化缓存、Tree Shaking、性能优化等核心特性,助你构建高效的前端工具链。

React Hooks深度解析:原理、最佳实践和性能优化

深入探讨React Hooks的内部实现原理,涵盖自定义Hooks开发、性能优化、常见陷阱以及最佳实践,帮助你更好地掌握React现代化开发。