Add support for AES encryption zip file
Add wzAES encryption & decryption (doc). min.js size just increase 13KB(from 96KB main dist). Support different password & encryptStrength and non-encrypt file mixed in single zip(use "password" & "encryptStrength(1|2|3, default 3(AES-256))" in file options or generate options). Thanks the very efficient crypto library sjcl.
Hi, @Stuk , I think this's pretty good for production, the min.js size only increase 13KB (107KB, gziped: 31KB) from the master branch (94KB, gziped: 27KB). And the speed & memory usage are quite fast & small for most users. Could you plz reiview this pr? thanks.
@xqdoo00o Thanks for your PR. I try to use this PR. But data is empty when saveas file zip and dowload. Could you check it?
const zip = new JSZip(); zip.file("Hello.txt", "Hello World\n");
const content = await zip.generateAsync({ type: "blob", password: "12345678", encryptStrength: 3, }); // const data = await JSZip.loadAsync(content, { password: "12345678" }); saveAs(content, "example.zip");
@xqdoo00o Thanks for your PR. I try to use this PR. But data is empty when saveas file zip and dowload. Could you check it?
const zip = new JSZip(); zip.file("Hello.txt", "Hello World\n");
const content = await zip.generateAsync({ type: "blob", password: "12345678", encryptStrength: 3, }); // const data = await JSZip.loadAsync(content, { password: "12345678" }); saveAs(content, "example.zip");
I tested with your code, it's ok. Did you recompile this PR use npm i & npm run test-browser,then use the js dist/jszip.js?
async function aaa(){
const zip = new JSZip();
zip.file("Hello.txt", "Hello World\n");
const content = await zip.generateAsync({
type: "blob",
password: "12345678",
encryptStrength: 3,
});
console.log(content);
saveAs(content, "example.zip");
}
aaa()
const zip = new JSZip(); zip.file("Hello.txt", "Hello World\n"); const content = await zip.generateAsync({ type: "blob", password: "12345678", encryptStrength: 3, }); console.log(content); saveAs(content, "example.zip");
@xqdoo00o Yes, I already recompile it. When i unzip the file with password, the data is empty. I didn't see any thing text such as Hello Word. I use MacOs.
const zip = new JSZip(); zip.file("Hello.txt", "Hello World\n"); const content = await zip.generateAsync({ type: "blob", password: "12345678", encryptStrength: 3, }); console.log(content); saveAs(content, "example.zip");
@xqdoo00o Yes, I already recompile it. When i unzip the file with password, the data is empty. I didn't see any thing text such as Hello Word. I use MacOs.
Chrome or Safari? Any errors in console? Same bug if using the origin
jszip.js?
I use chrome. I think i use jszip of this PR. if it is origin i can't input password when unzip, right?

There is any plan to merge this PR?
I would love to see this merged as well. While I'm no maintainer of this projects, I ask myself if it wouldn't be better to reference sjcl as a dependency in package.json instead of copying the sjcl.js file into the jszip repo? Wouldn't it help with keeping the version up to date? On the other hand, the sjcl was last changed about 2 years ago, maybe it's that stable that it doesn't need updates at all?
I would love to see this merged as well. While I'm no maintainer of this projects, I ask myself if it wouldn't be better to reference sjcl as a dependency in package.json instead of copying the sjcl.js file into the jszip repo? Wouldn't it help with keeping the version up to date? On the other hand, the sjcl was last changed about 2 years ago, maybe it's that stable that it doesn't need updates at all?
1, The origin sjcl does't have the module system, you have to use global variable to reference it. so I modify some code to fulfill the requirement(module export, pbkdf2 & ctr algorithm etc.) and reduce the code size. 2, I think the algorithm code will not change anymore since it has been used so long time.
Hello, we can pull your commit, build it and use the encryption for JSZip?
Hello, we can pull your commit, build it and use the encryption for JSZip?
Of course you can.
Hello, we can pull your commit, build it and use the encryption for JSZip?
Of course you can.
Great, I will give it a try to see if password works.
xqdoo00o: I have a question: would the WinZip AES encryption/decryption not also work "out of the box" with crypto.subtle.encrypt (or .decrypt), i. e. the "WebCrypto"? Probably this counter mode is not standard and the problem?
Is it possible to contact you via e-mail as I would also like to be able to decrypt single files (from a AES-ZIP) with my open source library, which I published on Github here: https://github.com/smartinmedia/Net-Core-JS-Encryption-Decryption ?
My e-mail is m (dot) weihrauch (at) smartinmedia (dot) com
Martin
xqdoo00o: I have a question: would the WinZip AES encryption/decryption not also work "out of the box" with crypto.subtle.encrypt (or .decrypt), i. e. the "WebCrypto"? Probably this counter mode is not standard and the problem?
Is it possible to contact you via e-mail as I would also like to be able to decrypt single files (from a AES-ZIP) with my open source library, which I published on Github here: https://github.com/smartinmedia/Net-Core-JS-Encryption-Decryption ?
My e-mail is m (dot) weihrauch (at) smartinmedia (dot) com
Martin
Yes, It can be impl with WebCrypto Api, but the counter mode is a big issue, you have to do a manual counter every 16 bytes(also see zip.js). Use sjcl is a solution (you could compare zip.js encrypt speed before and after using sjcl), or you could try Promise.all to parallel run crypto.subtle.encrypt func to optimize the speed, but I wonder if it really works because there could have too much Promise instance and function call stack if encrypt big files.
Would love to see it merged, I use it and it works flawlessly for me. (Here: https://github.com/imp0rtp3/Yobi).
+1 for merge
I tried @xqdoo00o fork but generated files didn't had a password at all
I tried @xqdoo00o fork but generated files didn't had a password at all
How do you generate files, show the code.
jQuery("#blob").on("click", function () {
async function aaa() {
const zip = new JSZip();
zip.file("Hello.txt", "Hello World\n");
const content = await zip.generateAsync({
type: "blob",
password: "12345678",
encryptStrength: 3,
});
console.log(content);
saveAs(content, "example222.zip");
}
aaa();
});
I need a code compatible with FF, chrome and IE11
jQuery("#blob").on("click", function () { async function aaa() { const zip = new JSZip(); zip.file("Hello.txt", "Hello World\n"); const content = await zip.generateAsync({ type: "blob", password: "12345678", encryptStrength: 3, }); console.log(content); saveAs(content, "example222.zip"); } aaa(); });I need a code compatible with FF, chrome and IE11
It should work. Did you recompile this PR use npm i & npm run test-browser,then use the js dist/jszip.js
I cloned your repo, I didn't use this PR. The browser tests hang there (using firefox)
I cloned your repo, I didn't use this PR. The browser tests hang there (using firefox)
Never mind, just terminate the test-browser, and use js dist/jszip.js
No password set. I attach full code:
<html>
<head>
<script type="text/javascript" src="vendor/FileSaver.js"></script>
<script type="text/javascript" src="dist/jszip.js"></script>
<!-- <script
type="text/javascript"
src="//stuk.github.io/jszip-utils/dist/jszip-utils.js"
></script> -->
<script type="text/javascript">
var zip = new JSZip();
zip.file("Hello.txt", "Hello World444\n");
// var img = zip.folder("images");
// img.file("smile.gif", imgData, { base64: true });
zip.generateAsync({
type: "blob",
password: "12345678",
encryptStrength: 3,
}).then(function (content) {
// see FileSaver.js
saveAs(content, "example444.zip");
});
</script>
</head>
<body>
Lorem ipsum
</body>
</html>
*removed jQuery, and ensured it works on firefox and IE11 (except password part)
After purging the dist files, and recreating them, now it fails:
Uncaught TypeError: JSZip is not a constructor
I cannot create de dist files if I delete them.
enboig@:/var/www/html/jszip(master)$ node --version
v14.18.0
enboig@:/var/www/html/jszip(master)$ npm --version
7.22.0
enboig@:/var/www/html/jszip(master)$ npm run test-browser
> [email protected] test-browser
> grunt build && grunt test
Running "browserify:all" (browserify) task
>> Error: module not found: "/var/www/html/jszip/lib/index.js" from file /var/www/html/jszip/lib/_fake.js
Warning: Error running grunt-browserify. Use --force to continue.
Aborted due to warnings.
I forgot to
1. In `package.json` temporarily change `"./lib/index"` to `"."`
Now it gets generated and appear to work
Files are missing CRC; is this accidental or adding CRC may lead to less secured files?
CompressedObject.createWorkerFrom = function (uncompressedWorker, compression, compressionOptions, encryptOptions) {
if (encryptOptions.password !== null) {
return uncompressedWorker
.pipe(new DataLengthProbe("uncompressedSize"))
.pipe(new Crc32Probe()) // <----missing
.pipe(compression.compressWorker(compressionOptions))
.pipe(aes.EncryptWorker(encryptOptions))
.pipe(new DataLengthProbe("compressedSize"))
.withStreamInfo("compression", compression);
} else {
return uncompressedWorker
.pipe(new Crc32Probe())
.pipe(new DataLengthProbe("uncompressedSize"))
.pipe(compression.compressWorker(compressionOptions))
.pipe(new DataLengthProbe("compressedSize"))
.withStreamInfo("compression", compression);
}
};
Files are missing CRC; is this accidental or adding CRC may lead to less secured files?
CompressedObject.createWorkerFrom = function (uncompressedWorker, compression, compressionOptions, encryptOptions) { if (encryptOptions.password !== null) { return uncompressedWorker .pipe(new DataLengthProbe("uncompressedSize")) .pipe(new Crc32Probe()) // <----missing .pipe(compression.compressWorker(compressionOptions)) .pipe(aes.EncryptWorker(encryptOptions)) .pipe(new DataLengthProbe("compressedSize")) .withStreamInfo("compression", compression); } else { return uncompressedWorker .pipe(new Crc32Probe()) .pipe(new DataLengthProbe("uncompressedSize")) .pipe(compression.compressWorker(compressionOptions)) .pipe(new DataLengthProbe("compressedSize")) .withStreamInfo("compression", compression); } };
The CRC is not useful in AE-2 encrypted zip. The document on this PR first line has explained doc.
Sorry, I didn't read de link; I compared a file created with jszip and the same created using ark (KDE utility to create zips), and the second one has CRC.
Hi,
I found some weird behaviour. I'm using your pull request to encrypt the zips I generate. I'm adding a self-generated csv file to the zips (using the stringify() module from csvjs.org). I found that this csv gets corrupted when i turn on encryption on the zips. I was using the default STORE compression type (no compression). After i either stopped encrypting or changed to DEFLATE, my csv is valid.
Other documents I am adding to the zip do not have this problem. Also, a plain text i added file did not suffer the problem.
Anyone interested in this problem? What do you need to analyse? My project is not public, but i could share the piece of code to reproduce.
And thanks for this pull request!
Hi,
I found some weird behaviour. I'm using your pull request to encrypt the zips I generate. I'm adding a self-generated csv file to the zips (using the stringify() module from csvjs.org). I found that this csv gets corrupted when i turn on encryption on the zips. I was using the default STORE compression type (no compression). After i either stopped encrypting or changed to DEFLATE, my csv is valid.
Other documents I am adding to the zip do not have this problem. Also, a plain text i added file did not suffer the problem.
Anyone interested in this problem? What do you need to analyse? My project is not public, but i could share the piece of code to reproduce.
And thanks for this pull request!
Hi, could you add some minimal reproduce demo? By the way, you don't need to stringify csv file to zip, just add blob or arraybuffer of the csvfile.