我肯定做错了,但是我似乎找不到。我使用了两个不同的库,并且有完全相同的错误。请帮助我找出我的代码有什么问题。我做了一个最小的版本来演示我的案子:
<script src="lib/FileSaver.js"></script>
<script>
window.addEventListener('load', function() {
document.getElementById("form_test").addEventListener('submit', function(e) {
e.preventDefault();
var worker = new Worker('worker.js');
var file = document.getElementById("testfile").files[0];
var key = document.getElementById("test_key").value;
worker.postMessage({ op:'test', file:file, password:key, bits:256 });
worker.onmessage = function(msg) {
console.dir(msg);
if (msg.data.progress == 'complete') {
saveAs(new Blob([msg.data.plaintext.data]), file.name);
// save decrypted file
}
}
});
});
</script>
<h1>Test file upload</h1>
<form id="form_test">
<input type="file" name="testfile" id="testfile" />
<input type="text" name="test_key" id="test_key" />
<input type="submit" />
</form>
this.importScripts('./lib/forge.min.js');
this.importScripts('./helpers.js');
this.onmessage = function(msg) {
switch (msg.data.op) {
case 'test':
console.dir(msg);
var reader = new FileReaderSync();
var file = reader.readAsText(msg.data.file, 'utf-8');
var key = msg.data.password;
var encryptedFile = encrypt(key, file);
var clearFile = decrypt(key, encryptedFile);
console.log(clearFile);
this.postMessage({ progress: 'complete', plaintext: clearFile });
break;
}
};
function basename(str)
{
var base = new String(str).substring(str.lastIndexOf('/') + 1);
if(base.lastIndexOf(".") != -1)
base = base.substring(0, base.lastIndexOf("."));
return base;
}
String.prototype.getBytes = function() {
var bytes = [];
for (var i = 0; i < this.length; i++) {
var charCode = this.charCodeAt(i);
var cLen = Math.ceil(Math.log(charCode)/Math.log(256));
for (var j = 0; j < cLen; j++) {
bytes.push((charCode << (j*8)) & 0xFF);
}
}
return bytes;
}
// ================================================================
// Utility function to generate the passwords in a canonical way.
// ================================================================
function make_password_bytes(password) {
var bytes = password.getBytes();
// Round to the nearest power of 2 larger than the password size and
// append bytes from the password. This allows us to regenerate it at
// will from the original.
var nearest_power_of_2 = Math.pow( 2, Math.ceil( Math.log( bytes.length ) / Math.log( 2 ) ) );
if (bytes.length != nearest_power_of_2) {
var remainder = nearest_power_of_2 - bytes.length;
for(var i=0; i<remainder; i++) {
var j = i % bytes.length;
bytes.push(bytes[j]);
}
}
return bytes;
}
// ================================================================
// Encrypt the data.
// ================================================================
function encrypt(password, data) {
var key = make_password_bytes(password);
var iv = forge.random.getBytesSync(16);
var cipher = forge.cipher.createCipher('AES-CBC', key);
cipher.start({iv: iv});
cipher.update(forge.util.createBuffer(data));
cipher.finish();
var encrypted = cipher.output;
var data = forge.util.bytesToHex(encrypted);
var obj = {'iv': forge.util.bytesToHex(iv), 'encrypted': data};
return JSON.stringify(obj); // String rep allows persistence.
}
// ================================================================
// Decrypt the data.
// ================================================================
function decrypt(password, encrypted) {
var key = make_password_bytes(password);
var obj = JSON.parse(encrypted);
var iv = forge.util.createBuffer();
var data = forge.util.createBuffer();
iv.putBytes(forge.util.hexToBytes(obj.iv));
data.putBytes(forge.util.hexToBytes(obj.encrypted));
var decipher = forge.cipher.createDecipher('AES-CBC', key);
decipher.start({iv: iv});
decipher.update(data);
decipher.finish();
return decipher.output;
}
FileSaver:https://raw.githubusercontent.com/eligrey/FileSaver.js/master/dist/FileSaver.js
伪造:https://cdn.jsdelivr.net/npm/node-forge@0.7.0/dist/forge.min.js
已加密然后解密的文件无法打开。而且奇怪的是,当我查看其hexdump
时,它看起来很像原始的,但是有一些额外的字节:
$ hexdump -C file.png | head
00000000 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|
00000010 00 00 01 15 00 00 01 52 08 06 00 00 00 dc b3 4b |.......R.......K|
00000020 36 00 00 18 44 69 43 43 50 49 43 43 20 50 72 6f |6...DiCCPICC Pro|
00000030 66 69 6c 65 00 00 58 85 95 59 05 58 94 cb d7 9f |file..X..Y.X....|
00000040 77 93 85 5d ba bb bb 3b a4 bb a4 1b 81 65 a9 a5 |w..]...;.....e..|
00000050 a5 41 10 09 51 e2 0a 16 2a a0 48 89 48 09 06 88 |.A..Q...*.H.H...|
00000060 88 80 84 28 82 84 80 60 00 0a 0a a2 62 a0 28 f5 |...(...`....b.(.|
00000070 bd 80 7a ef ff fe 9f e7 fb 9e 6f f6 99 f7 fd ed |..z.......o.....|
00000080 99 33 67 ce 9c 33 73 66 ce 2e 00 1c 8a c4 f0 f0 |.3g..3sf........|
00000090 60 04 2d 00 21 a1 51 11 b6 c6 7a bc ce 2e ae bc |`.-.!.Q...z.....|
$
$ hexdump -C file\ (1).png | head # <-- autorenamed because filename already existed
00000000 c3 bd 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 |..PNG........IHD|
00000010 52 00 00 01 15 00 00 01 52 08 06 00 00 07 33 4b |R.......R.....3K|
00000020 36 00 00 18 44 69 43 43 50 49 43 43 20 50 72 6f |6...DiCCPICC Pro|
00000030 66 69 6c 65 00 00 c2 a7 02 c3 bd 59 05 c2 a7 c3 |file.......Y....|
00000040 bd c3 b8 c3 9f c2 88 c3 bd c3 bd c2 a2 02 c3 bd |................|
00000050 c3 bd c3 84 02 c3 bd c3 bd c3 a4 c3 bd 65 02 02 |.............e..|
00000060 c3 bd 41 10 09 c2 ae c3 bd 0a 16 c3 95 c3 bd c2 |..A.............|
00000070 b7 c3 bd 48 09 c3 b9 02 02 c3 bd c3 bd c3 97 02 |...H............|
00000080 c3 bd c3 bd 60 00 0a c3 b5 c3 bd c2 9d c3 bd c3 |....`...........|
00000090 97 02 02 c3 bd c2 85 02 02 c3 bd 02 02 02 c3 bd |................|
如您所见,它确实很接近,几乎相似,我不明白为什么。
我在worker.js第13行中添加了它:
console.dir({
original: file,
now: clearFile.data
});
它说:
似乎是编码问题...