英文:
Encrypt File from browser AES-GCM
问题
我使用AES GCM加密和解密文件时遇到了问题,我使用以下代码进行加密/解密:
我尝试了许多库,但它们没有解决我的问题。
var FileSaver = require("file-saver");
export function formatBytes(bytes) {
// ...
}
export const encryptFile = async (key, iv, file) => {
// ...
};
// ...
文件可以加密/解密,但它们可以使用任何密码解密,即使与加密时使用的密码不匹配。我在这里漏掉了什么?
英文:
I have a problem with encrypting and decrypting files with AES GCM, I encrypt/decrypt my files with this code:
I tried many some libraries but they didnt solve my problem.
var FileSaver = require("file-saver");
export function formatBytes(bytes) {
var marker = 1024; // Change to 1000 if required
var decimal = 3; // Change as required
var kiloBytes = marker; // One Kilobyte is 1024 bytes
var megaBytes = marker * marker; // One MB is 1024 KB
var gigaBytes = marker * marker * marker; // One GB is 1024 MB
// return bytes if less than a KB
if (bytes < kiloBytes) return bytes + " Bytes";
// return KB if less than a MB
else if (bytes < megaBytes)
return (bytes / kiloBytes).toFixed(decimal) + " KB";
// return MB if less than a GB
else if (bytes < gigaBytes)
return (bytes / megaBytes).toFixed(decimal) + " MB";
// return GB if less than a TB
else return (bytes / gigaBytes).toFixed(decimal) + " GB";
}
export const encryptFile = async (key, iv, file) => {
return await window.crypto.subtle.encrypt(
{
name: "AES-GCM",
iv: iv
},
key,
file
);
};
/*
Get some key material to use as input to the deriveKey method.
The key material is a password supplied by the user.
*/
export const getKeyMaterial = async (password) => {
let enc = new TextEncoder();
return window.crypto.subtle.importKey(
"raw",
enc.encode(password),
{ name: "PBKDF2" },
false,
["deriveBits", "deriveKey"]
);
};
/*
Given some key material and some random salt
derive an AES-GCM key using PBKDF2.
*/
export const getKey = async (keyMaterial, salt) => {
return window.crypto.subtle.deriveKey(
{
name: "PBKDF2",
salt: salt,
iterations: 100000,
hash: "SHA-256"
},
keyMaterial,
{ name: "AES-GCM", length: 256 },
true,
["encrypt", "decrypt"]
);
};
// get the iv which is similar the salt value used for encryption
export const getiv = () => {
return window.crypto.getRandomValues(new Uint8Array(12));
};
// load the file in the memory
export const getFile = async (inputFile) => {
return await inputFile.arrayBuffer();
};
export const decryptFile = (iv, key, cipherText) => {
return window.crypto.subtle.decrypt(
{
name: "AES-GCM",
iv: iv
},
key,
cipherText
);
};
export const getDigest = (uid) => {
let enc = new TextEncoder();
return crypto.subtle.digest("SHA-256", enc.encode(uid));
};
export const startEncryption = async (file, password) => {
console.log(file, password);
let digest = getDigest(password);
let rawFile = getFile(file);
let keyMaterial = getKeyMaterial();
Promise.all([digest, rawFile, keyMaterial]).then((values) => {
console.log(values);
let salt = new Uint8Array(
"12345678".match(/[\da-f]{2}/gi).map(function (h) {
return parseInt(h, 16);
})
);
let iv = new Uint8Array(
"4142434445464748494a4b4c4d4e4f50"
.match(/[\da-f]{2}/gi)
.map(function (h) {
return parseInt(h, 16);
})
);
// generate a crypto key
getKey(values[2], salt).then((resp) => {
console.log(resp);
encryptFile(resp, iv, values[1]).then((cipherText) => {
let fileBlob = new Blob([cipherText], { type: file.type });
FileSaver.saveAs(fileBlob, file.name);
});
});
});
};
export const startDecryption = (cipherText, password) => {
let keyMaterial = getKeyMaterial();
let digest = getDigest(password);
let rawFile = getFile(cipherText);
Promise.all([digest, rawFile, keyMaterial]).then((values) => {
let salt = new Uint8Array(
"12345678".match(/[\da-f]{2}/gi).map(function (h) {
return parseInt(h, 16);
})
);
let iv = new Uint8Array(
"4142434445464748494a4b4c4d4e4f50"
.match(/[\da-f]{2}/gi)
.map(function (h) {
return parseInt(h, 16);
})
);
// generate a crypto key
getKey(values[2], salt).then((resp) => {
decryptFile(iv, resp, values[1]).then((file) => {
let fileBlob = new Blob(, { type: file.type });
FileSaver.saveAs(fileBlob, file.name);
});
});
});
};
Files can be encrypt/decrypted but they can be decrypted with any password even if it doesnt match the password it encrypted with.
What am i missing here?
答案1
得分: 2
你调用了getKeyMaterial()
,但没有提供密码,因此它始终是未定义的。
尝试使用getKeyMaterial(password);
。
英文:
you call getKeyMaterial() without the password, so its always undefined.
try getKeyMaterial(password);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论