Files
XiangYue/js/encryption-method-1.js
风之暇想 68f69a96c7 v1.0
正式版
2025-07-10 14:48:50 +08:00

3 lines
4.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const encryptionMethod1={async deriveKey(password,salt){try{const passwordBuffer=utils.stringToArrayBuffer(password);const pbkdf2Key=await crypto.subtle.importKey('raw',passwordBuffer,{name:'PBKDF2'},false,['deriveBits']);const pbkdf2Bits=await crypto.subtle.deriveBits({name:'PBKDF2',salt,iterations:500000,hash:'SHA-256'},pbkdf2Key,512);const hkdfKey=await crypto.subtle.importKey('raw',pbkdf2Bits,{name:'HKDF'},false,['deriveBits']);const aesBits=await crypto.subtle.deriveBits({name:'HKDF',hash:'SHA-256',salt:new Uint8Array(0),info:utils.stringToArrayBuffer('AES-CTR')},hkdfKey,256);const chachaBits=await crypto.subtle.deriveBits({name:'HKDF',hash:'SHA-256',salt:new Uint8Array(0),info:utils.stringToArrayBuffer('ChaCha20')},hkdfKey,256);const aesCtrKey=await crypto.subtle.importKey('raw',aesBits,{name:'AES-CTR'},false,['encrypt','decrypt']);return{aesCtrKey,chachaKey:new Uint8Array(chachaBits)};}catch(error){console.error('密钥派生失败:',error);throw new Error('密钥派生过程发生错误,请检查输入参数');}},async encryptAESCTR(plaintext,key){try{const counter=utils.generateRandomBytes(16);const encrypted=await crypto.subtle.encrypt({name:'AES-CTR',counter,length:128},key,plaintext);return new Uint8Array([...counter,...new Uint8Array(encrypted)]).buffer;}catch(error){console.error('AES-CTR加密失败:',error);throw new Error('AES-CTR加密过程发生错误');}},async decryptAESCTR(ciphertext,key){try{const counter=ciphertext.slice(0,16);const encrypted=ciphertext.slice(16);return crypto.subtle.decrypt({name:'AES-CTR',counter,length:128},key,encrypted);}catch(error){console.error('AES-CTR解密失败:',error);throw new Error('AES-CTR解密过程发生错误可能密钥不正确');}},async encryptChaCha20Poly1305(plaintext,key){try{const nonce=sodium.randombytes_buf(12);const encrypted=sodium.crypto_aead_chacha20poly1305_ietf_encrypt(new Uint8Array(plaintext),null,null,nonce,key);return new Uint8Array([...nonce,...encrypted]).buffer;}catch(error){console.error('ChaCha20加密失败:',error);throw new Error('ChaCha20加密过程发生错误');}},async decryptChaCha20Poly1305(ciphertext,key){try{const nonce=ciphertext.slice(0,12);const encrypted=ciphertext.slice(12);return sodium.crypto_aead_chacha20poly1305_ietf_decrypt(null,new Uint8Array(encrypted),null,new Uint8Array(nonce),key);}catch(error){console.error('ChaCha20解密失败:',error);throw new Error('ChaCha20解密过程发生错误可能密钥或数据已损坏');}},isBase64(str){return/^[A-Za-z0-9+/=]+$/.test(str);},async encrypt(plaintext,password,isBase64Enabled=true){try{const salt=utils.generateRandomBytes(16);const{aesCtrKey,chachaKey}=await this.deriveKey(password,salt);const compressed=await utils.compressData(utils.stringToArrayBuffer(plaintext));const aesCtrEncrypted=await this.encryptAESCTR(compressed,aesCtrKey);const chachaEncrypted=await this.encryptChaCha20Poly1305(aesCtrEncrypted,chachaKey);const combined=new Uint8Array([...salt,...new Uint8Array(chachaEncrypted)]);let result=utils.arrayBufferToBase64(combined.buffer);if(!isBase64Enabled){result=mappingMode1.base64ToChinese(result);}
return result;}catch(error){console.error('数据加密失败:',error);throw new Error(`加密过程发生错误: ${error.message}`);}},async decrypt(ciphertext,password){try{let processedCiphertext=ciphertext;if(!this.isBase64(ciphertext)){processedCiphertext=mappingMode1.chineseToBase64(ciphertext);}
const ciphertextBuffer=utils.base64ToArrayBuffer(processedCiphertext);const salt=ciphertextBuffer.slice(0,16);const encryptedData=ciphertextBuffer.slice(16);const{aesCtrKey,chachaKey}=await this.deriveKey(password,salt);const chachaDecrypted=await this.decryptChaCha20Poly1305(encryptedData,chachaKey);const aesCtrDecrypted=await this.decryptAESCTR(chachaDecrypted,aesCtrKey);return utils.arrayBufferToString(await utils.decompressData(aesCtrDecrypted));}catch(error){console.error('数据解密失败:',error);if(error.message.includes('decryption failed')){throw new Error('解密失败:可能密码错误或数据已损坏');}else if(error.message.includes('key derivation')){throw new Error('密钥派生失败:请检查密码长度和复杂度');}else{throw new Error(`解密过程发生错误: ${error.message}`);}}}};