yii2-netdisk/web/js/vault_core.js

86 lines
3.1 KiB
JavaScript
Raw Normal View History

const vaultRawKey = sessionStorage.getItem('vaultRawKey');
async function getSaltFromBackend() {
const response = await fetch('index.php?r=vault%2Fget-salt');
const data = await response.json();
return data.vault_salt;
}
async function deriveKey(password) {
const passwordBuffer = new TextEncoder().encode(password);
const salt = await getSaltFromBackend();
const saltBuffer = new TextEncoder().encode(salt);
const key = await window.crypto.subtle.importKey(
'raw',
passwordBuffer,
{name: 'PBKDF2'},
false,
['deriveKey']
);
return await window.crypto.subtle.deriveKey(
{
name: 'PBKDF2',
salt: saltBuffer,
iterations: 100000,
hash: 'SHA-256'
},
key,
{name: 'AES-GCM', length: 256},
false, // 是否允许导出
['encrypt', 'decrypt']
);
}
async function encryptFile(file, password) {
const iv = window.crypto.getRandomValues(new Uint8Array(12));
const derivedKey = await deriveKey(password);
// console.log(password);
const plaintextData = await file.arrayBuffer();
const encryptedData = await window.crypto.subtle.encrypt(
{name: 'AES-GCM', iv: iv, tagLength: 128},
derivedKey,
plaintextData
);
return new Blob([iv, encryptedData], {type: file.type});
}
async function decryptFile(encryptedFile, password) {
const encryptedData = new Uint8Array(await encryptedFile.arrayBuffer());
const iv = encryptedData.slice(0, 12);
const ciphertext = encryptedData.slice(12);
const derivedKey = await deriveKey(password);
const decryptedData = await window.crypto.subtle.decrypt(
{name: 'AES-GCM', iv: iv, tagLength: 128},
derivedKey,
ciphertext
);
return new Blob([decryptedData], {type: encryptedFile.type});
}
// async function decryptFile(encryptedFile, password) {
// const encryptedData = new Uint8Array(await encryptedFile.arrayBuffer());
// const iv = encryptedData.slice(0, 12);
// const ciphertext = encryptedData.slice(12);
// const derivedKey = await deriveKey(password);
// const keyData = await window.crypto.subtle.exportKey('raw', derivedKey);
// const keyBytes = new Uint8Array(keyData);
// // console.log('Key:', keyBytes);
// // console.log(password);
// const decryptedData = await window.crypto.subtle.decrypt(
// {name: 'AES-GCM', iv: iv, tagLength: 128},
// derivedKey,
// ciphertext
// );
// return new Blob([decryptedData], {type: encryptedFile.type});
// }
async function downloadAndDecryptFile(url, password, filename) {
const response = await fetch(url);
const encryptedFile = await response.blob();
const decryptedFile = await decryptFile(encryptedFile, password);
const blob = new Blob([decryptedFile], {type: decryptedFile.type});
const blobURL = window.URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = blobURL;
link.download = filename;
link.click();
window.URL.revokeObjectURL(blobURL);
}