pdf-lib
pdf-lib copied to clipboard
Dev/doc encrypt
Continuation of PR #917 & #243
Hope to get some advanced review on the PR as this is quite a significant addition,
What?
This PR add the feature for user to be able to Encrypt an unencrypted file.
Why?
Enables the encryption feature in this library
How?
On the branch, you can try it by using the scratchpad
yarn run scratchpad:start to start the build, then yarn scratchpad:run. It should create a new pdf in the root level. Then you can verify it.
const pdfDoc = await PDFDocument.create();
const existingPdfBytes = fs.readFileSync('test.pdf');
const pdfDoc = await PDFDocument.load(existingPdfBytes);
const page = pdfDoc.addPage();
page.drawText('Creating PDFs in JavaScript is awesome!', {
x: 50,
y: 700,
});
pdfDoc.encrypt({
userPassword: 'abcd',
ownerPassword: '1234',
permissions: { modifying: true },
});
// useObjectStreams true and false works
// note on the following section on bugs on adobe acrobat reader
const pdfBytes = await pdfDoc.save({ useObjectStreams: false });
fs.writeFileSync('sample.pdf', pdfBytes);
Testing?
Manual testing by verifying the permission in PDF Reader application.
Added Integration test test19.ts and test20.ts in node
File should only be able to open and get decrypted in the PDF Reader if everything is implemented correctly.
Suggestions on testing is welcomed.
New Dependencies?
Crypto.js
Saslprep
Both are famous public libraries.
Screenshots
N/A
Suggested Reading?
Yes
Anything Else?
There are 2 areas that I would need help with on this PR.
-
How to verify that the
buildis working, as raised in #917 -
Currently, there is a bug when using
pdfDoc.save({ useObjectStreams: true }), the file is not able to be opened inAdobe Acrobat Reader, but works fine on browser and other PDF readers.
Checklist
- [x] I read CONTRIBUTING.md.
- [x] I read MAINTAINERSHIP.md#pull-requests.
- [ ] I added/updated unit tests for my changes.
- [x] I added/updated integration tests for my changes.
- [x] I ran the integration tests.
- [x] I tested my changes in Node, ~~Deno~~, and the ~~browser~~.
- [x] I viewed documents produced with my changes in Adobe Acrobat, Foxit Reader, Firefox, and Chrome.
- [ ] I added/updated doc comments for any new/modified public APIs.
- [x] My changes work for both new and existing PDF files.
- [x] I ran the linter on my changes.
@PhakornKiong thanks for reopening this PR! It's pretty hefty, so it'll be awhile before I can look through all this.
Sidenote: If you'd like for folks to be able to use your work without waiting, you might consider making a separate library that people can pass a PDFDocument object to for encryption.
@PhakornKiong thanks for reopening this PR! It's pretty hefty, so it'll be awhile before I can look through all this.
Sidenote: If you'd like for folks to be able to use your work without waiting, you might consider making a separate library that people can pass a
PDFDocumentobject to for encryption.
No worries, take your time.
It would be difficult to spin off as a separate library as the change rely heavily on the pdfWriter to write the encrypted content into the file.
This looks awesome; it would be great to see this pulled in and also the ability to decrypt pdfs =] (dealing with that now, trying to decide how to handle it)
Hi, how can I use it in a browser environment? It seems that npm run build creates a dist compatible only with node In my case the inclusion of the saslprep library produced a few lines of code that point directly to the local filesystem to access code-point.mem Can you add some instruction on how to use this mod in standard web pages? Thanks and congratulations again for the excellent work done
Hello,
I'm very interested by this one. Any chance to see this feature added in the near future ?
Thanks.
Hey @Hopding @PhakornKiong, this feature is a great and i see how it could re written outside of pdf-lib so i can keep using the latest release without doing any refactoring in the future, but before i do is it going to be added in the near future? Not a problem at all just curious.
Hey @Hopding @PhakornKiong, this feature is a great and i see how it could re written outside of pdf-lib so i can keep using the latest release without doing any refactoring in the future, but before i do is it going to be added in the near future? Not a problem at all just curious.
At this rate, i doubt it will be merge anytime soon. Might be a great solution to those that need this functionality.
How would you write it outside of pdf-lib ? (Just curious, since i relied heavily on the parser in pdf-lib)
Hey @Hopding @PhakornKiong, this feature is a great and i see how it could re written outside of pdf-lib so i can keep using the latest release without doing any refactoring in the future, but before i do is it going to be added in the near future? Not a problem at all just curious.
At this rate, i doubt it will be merge anytime soon. Might be a great solution to those that need this functionality.
How would you write it outside of pdf-lib ? (Just curious, since i relied heavily on the parser in pdf-lib)
This idea is really more a guess. But a while back I found a solution on here to update spot colours in a pdf and has been expanded for other features. So using the research from your blog plus the pdf specification I'm thinking that might work.
This would be incredibly useful for us. Any idea when it might get merged?
Hi~ @PhakornKiong the PR code I use cannot be opened in the adobe reader after encrypting the pdf in my workplace, but it can be opened in other pdf readers (the browser can be opened)
This feature would be immensely useful. I'm voting to move forward with merging. Any ETA?
@PhakornKiong What an incredible job!
Maybe, while this processes until merge, can you release your fork on npm?
+1 for adding it in. Anybody from the repo bossmen available for a review? @MatheusHCP I see it was approved, could we merge it in? @PhakornKiong Some merge conflicts here, a small fix for man, a giant PDF encryption leap for all developer kind. Plz resolve.
+1 for adding it in. Anybody from the repo bossmen available for a review? @MatheusHCP I see it was approved, could we merge it in? @PhakornKiong Some merge conflicts here, a small fix for man, a giant PDF encryption leap for all developer kind. Plz resolve.
Ok, let me do it this weekend.
Thanks so much @PhakornKiong!
This looks awesome; it would be great to see this pulled in and also the ability to decrypt pdfs =] (dealing with that now, trying to decide how to handle it)
decrypt is super helpful as well, any updates on this? thanks!
@PhakornKiong I fork your repo and build, but error about fs founded, would u kindly tell me how to build correctly?
Would love to get this implemented. As of right now, there are not a lot of ways to encrypt an already existing pdf using node.
@PhakornKiong Still some merge conflicts 🥲. Or are there some new ones now? Let's get this party started please.
@gonyulian415 are you using the correct version of nodejs?
Hey @peterpoliwoda, I faced 2 issues while building Phakorn's fork for browser.
- The fork uses
crypto-jsandsaslprep. Rollup config bundles them too when building theumdoresmpackage viayarn build:esmoryarn build:umd. - Even if you do not bundle
crypto-js(as most browsers support it),saslprephas statements likeconst fs = require('fs')which throws errors in browser.
Can you guide me how to bundle the fork to make it work on browser?
Edit:
- Resolved above two by dropping
crypto-jsduring build and includingsaslprepfrom https://github.com/foliojs/pdfkit/tree/master/lib/saslprep. - Another error popped up,
ReferenceError: Buffer is not definedwhich was quite easy to resolve.
npm install --save buffer
src/core/security/PDFSecurity.ts should be somewhat like this.
// import CryptoJS from 'crypto-js';
import { Buffer } from 'buffer';
import saslprep from './saslprep/index';
@gonyulian415 Please go through this once and let me know whether your issue is resolved or not
Awesome! Well done sir!
Hell
Awesome! Well done sir!
Hello, I want to ask this feature will be merge or still is review?
Closing this? So is there no hope for this to go in? What's happening?
@peterpoliwoda I forced pushed and it automatically closed it, probably have to do with history
Hi @PhakornKiong, with encryption enabled (ownerPassword and permissions only), document's metadata seems to be encrypted as well. Is this expected result or a bug?
| Without Encryption | With Encryption |
|---|---|
Hi @PhakornKiong, with encryption enabled (
ownerPasswordandpermissionsonly), document's metadata seems to be encrypted as well. Is this expected result or a bug?Without Encryption With Encryption
![]()
I'm not 100% sure, would need to check the standard to verify.
What tools do you use to display this? Maybe i can take a peek
Left is unencrypted, middle is encrypted by ilovepdf, right is from the PR
What tools do you use to display this? Maybe i can take a peek
Simply viewing the pdf in MS Edge (chromium to be specific).
Left is unencrypted, middle is encrypted by ilovepdf, right is from the PR
Both the images of the encrypted pdf are not showing the metadata.
Also from Adobe Acrobat Reader
Created a sample pdf usingjsPDF with ownerPassword and permissions only. The metadata is intact.
The more modern PDF encryption methods allow the file’s XMP metadata stream (XML Metadata) to be left unencrypted so it may be extracted and read by programs which don’t know how to open encrypted PDF files, or if the password is not known.^1
I'm of the opinion that the default is to encrypt metadata. So probably i would not change this implementation here.
https://opensource.adobe.com/dc-acrobat-sdk-docs/pdfstandards/PDF32000_2008.pdf
The encryption is grate, however I’m facing the same issue as PROxZIMA ,metadata are also encrypted, and I can’t reset team by pdfDoc.setTitle(“”) (same as setAuthor, setSubject)
In most PDF encryption apps and libraries there is an option to enable/disable the encryption of document metadata. I would recommend adding this option so that the developer can choose to encrypt the metadata or leave as-is.

