npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

pdf-signatures

v0.1.0

Published

Sign PDFs with electronic signatures in Nodejs

Downloads

296

Readme

Build Status

PDF-Signatures

Sign PDFs with PKCS7 signatures like a boss!

Dependencies

  • UNIX-like OS
  • Java runtime >= 1.8
  • Nodejs >= 8.10

License

This library is distributed under the AGPL license. However, some dependencies may be licenced under different licence types.

See https://www.gnu.org/licenses/agpl-3.0.en.html.

Testing

  • npm run lint
  • npm run test
  • ./gradlew checkstyleMain
  • ./gradlew test

Building (Before publishing an npm package)

  • gradle build
  • gradle copyJarToLibs
  • gradle clean (optional)

Usage (Nodejs)

Add signature placeholder

const { addSignaturePlaceholderToPdf, CertificationLevels } = require('pdf-signatures');

const outputPath = await addSignaturePlaceholderToPdf({
  file: '/path/to/file.pdf',                   // Path to file, Required
  out: '/path/to/out.pdf',                     // Output file path, Required
  estimatedsize: 30000,                        // Estimated signature size, Optional, Default is 30000
  certlevel: CertificationLevels.NotCertified, // Certification level, Optional, Default is CertificationLevels.NotCertified
  password: '123456',                          // Document password, Optional
  reason: 'I want to sign the document',       // Signing reason, Optional, Default is undefined
  location: 'Moon',                            // Signing location, Optional, Default is undefined
  contact: 'John Doe',                         // Signing contact, Optional, Default is undefined
  date: '2019-09-26T20:54:41.426Z',            // Signing date in ISO-8601 format, Optional, Default is undefined
});

Calculate document digest

const { preparePdf, HashAlgorithms } = require('pdf-signatures');

const base64EncodedDigest = await pdfDigest({
  file: '/path/to/file.pdf',                   // Path to file, Required
  password: '123456',                          // Document password, Optional
  algorithm: HashAlgorithms.Sha512,            // Hash algorithm, Optional, Default is HashAlgorithms.Sha512
});

Sign PDF with external signature

const outputPath = await signPdf({
  file: '/path/to/file.pdf',                   // Path to file, Required
  out: '/path/to/out.pdf',                     // Output file path, Required
  signature: 'base64',                         // Base64-encoded external signature
  password: '123456',                          // Document password, Optional
});

Embed LTV (Long Time Validation) information

const outputPath = await addLtvToPdf({
  file: '/path/to/file.pdf', // Path to file, Required
  out: '/path/to/out.pdf',   // Output file path, Required
  crl: [                     // Certificate revocation list (bbase64-encoded), Required
    'base64',
    'base64',
    '...'
  ],
  ocsp: [                    // Online certificate status protocol responses list, (base64-encoded), Required
    'base64',
    'base64',
    '...'
  ],
});

Usage (Jar)

General invokation format:

$ java -jar <path-to-jar> <arguments>

Where <arguments> is one of the following:

Advanon PKCS7 document signer

Usage:
  help                                        Show this help
  version                                     Display current version number
  --version                                   Display current version number
  -v                                          Display current version number
  placeholder                                 Add a signature placeholder
    --file <path>                             Path to the document
    --out <path>                              Path where to save a new document
    [--estimatedsize <int>]                   Estimated signature size, default is 30000 bytes
    [--certlevel <int>]                       Desired certification level, default is 0
      * 0                                     Not certified
      * 1                                     Certified, no changes allowed
      * 2                                     Certified, form filling
      * 3                                     Certified, form filling and annotations
    [--password <string>]                     Document password
    [--reason <reason>]                       Signing reason
    [--location <location>]                   Signing location
    [--contact <contact>]                     Signing contact
    [--date <contact>]                        Date of signing in ISO 8601 format
  digest                                      Calculate document digest excluding signatures
    --file <path>                             Path to the document
    [--password <string>]                     Document password
    [--algorithm <SHA-256|SHA-384|SHA-512>]   Encryption algorithm, default is SHA-512
  sign                                        Sign the document with external signature
    --file <path>                             Path to the document
    --out <path>                              Path where to save a new document
    --signature <base64 string>               Base64-encoded signature
    [--password <string>]                     Document password
  ltv                                         Add LTV information to the document
    --file <path>                             Path to the document
    --out <path>                              Path where to save a new document
    --crl <base64 string>...                  Base64-encoded CRL (each single CRL should be prepended with -crl)
    --ocsp <base64 string>...                 Base64-encoded OCSP (each single OCSP should be prepended with -ocsp)
    [--password <string>]                     Document password

Example
  placeholder --file file.pdf --out placeholdered.pdf                                                                   Add signature placeholder
  digest --file placeholdered.pdf --algorithm sha512                                                                    Calculate document digest
  sign --file placeholdered.pdf --out signed.pdf --signature abb4rjfh=                                                  Sign the document with external signature
  ltv --file signed.pdf --out signedltv.pdf --crl abb4rjfh= --crl fgsllldj5kg= --oscp abb4rjfh= --ocsp fgsllldj5kg=     Insert LTV information into signed document

Notes

Pdf objects, their encoding, position and length

You may notice in the source code a some "magic" conversions, like (N + 2) / 2, or (X - 2 / 2), this is because PDF objects are HEX-encoded, which means that every two bytes of the PDF object you read is actually one HEX-digit.

For example, if you are writing byte 255 into PDF, you should bare in mind that this will (or at least that should) be actually written as FF which is now TWO! bytes.

Now you may wonder what does +2 or -2 mean. The answer is pretty straightforward - content of PDF objects begins with < and ends with >, and sometimes you simply don't need these markers taken into account.

Signature byte range and document hash

Every signature has a byte range information, which contains... a byte range of the signature and of the document content surrounding it.

For instance, consider the next byte range: [ 0, 200, 400, 250 ]:

|----------------------------|  0
| /Content <                 |
|----------------------------|  200
| signature HEX              |
|----------------------------|  400
| >                          |
|----------------------------|  650 (400 + 250)

When calculating hash of a signed document, signature bytes are exluded from the calculation. From the example, these are 200 bytes 200 -> 400.