javascriptnode.jspdfdigital-signature

How to Extract Digital Signatures from a PDF Using Node.js?


I'm trying to extract information about all the digital signatures in a PDF file using Node.js. I found a way to obtain some data that appears to contain this information, but it seems to be jumbled.

Here is my current code:

const forge = require("node-forge");
const fs = require("fs");
const { Buffer } = require("buffer");


function GetSignaturesByteRange(FileBuffer) {

    const ByteRangeList = [];

    let ByteRangeStart = 0;

    while ((ByteRangeStart = FileBuffer.indexOf("/ByteRange [", ByteRangeStart)) !== -1) {

        const ByteRangeEnd = FileBuffer.indexOf("]", ByteRangeStart);
        const ByteRange = FileBuffer.slice(ByteRangeStart, ByteRangeEnd + 1).toString();

        const ByteRangeString = /(\d+) +(\d+) +(\d+) +(\d+)/.exec(ByteRange);
        const ByteRangeArray = ByteRangeString.slice(1, 5).map(Number); // Convert to integers

        // Add the ByteRange to the list
        ByteRangeList.push(ByteRangeArray);

        // Move past the current ByteRange
        ByteRangeStart = ByteRangeEnd + 1;

    }

    return ByteRangeList;
}

function GetSignatureData(FileBuffer, ByteRange) {

    // Extract the specified range from the buffer
    let ByteRangeBuffer = FileBuffer.slice(ByteRange[1] + 1, ByteRange[2] - 1)

    // Remove the zeroes from the end of the buffer
    let EndIndex = ByteRangeBuffer.length;
    while (EndIndex > 0 && ByteRangeBuffer[EndIndex - 1] === 0x30) {
        EndIndex--;
    }

    ByteRangeBuffer = ByteRangeBuffer.slice(0, EndIndex);

    return ByteRangeBuffer.toString("binary");
}

const InputFile = fs.readFileSync("./signed.pdf");
const AllByteRanges = GetSignaturesByteRange(InputFile);

let SignatureBuffer = GetSignatureData(InputFile, AllByteRanges[0]);


console.log(SignatureBuffer);

fs.writeFileSync("Sigature.bin", Buffer.from(SignatureBuffer, "hex"));

The Signature.bin file produced by this code contains some data such as my name and city from when I digitally signed the PDF, but it is surrounded by what seems to be garbage data.

How can I properly extract and clean up the digital signature information from the PDF? Any advice or improvements to my code would be greatly appreciated!


Solution

  • I used the code from the broken npm package ninja-labs/verify-pdf and modified it to retrieve the data the code can be found on my github here