Skip to content

Issues with signing pdf file with certificate from azure certificate vault with non-exportable private key #272

@arvydas-kezunas

Description

@arvydas-kezunas

Greetings everyone, i am facing some issues with putting digital signatures on pdf files with using azure certificate vault. Problem appears when certificate is with non-exportable private key and have to rely on azure cryptography client. this is my current implementation:

   async signDocument(fileBuffer: Buffer, certName: string) {
    try {
      Logger.log(`Starting document signing process for certificate: ${certName}...`);

      Logger.log(`Retrieving certificate: ${certName} from Azure...`);
      const certificateData = await this.certificateClient.getCertificate(certName);

      Logger.log('Extracting Key ID from the certificate...');
      const keyId = certificateData.keyId;
      if (!keyId) {
        Logger.error('Key ID not found in the certificate.');
        throw new Error('Key ID not found for certificate');
      }
      Logger.log(`Key ID found: ${keyId}`);

      Logger.log(`Creating CryptographyClient with Key ID: ${keyId}...`);
      const cryptoClient = new CryptographyClient(keyId, this.credential);
      Logger.log('CryptographyClient created successfully.');

      Logger.log('Loading and modifying PDF document...');
      const pdfDoc = await PDFDocument.load(fileBuffer);
      pdflibAddPlaceholder({
        pdfDoc: pdfDoc,
        reason: 'I am the author of this document',
        location: 'Lithuania',
        contactInfo: 'namelastname@email.com',
        name: 'Name Lastname',
        widgetRect: [50, 100, 250, 150],
      });

      const pdfWithPlaceholderBytes = await pdfDoc.save();

      const documentHash = this.createHashWith(Buffer.from(pdfWithPlaceholderBytes));

      const signResult: SignResult = await cryptoClient.sign("RS256", documentHash);

      const azureSigner = new AzureVaultSigner(signResult.result);
      const signedPdfBytes = await SignPdf.sign(pdfWithPlaceholderBytes, azureSigner);

      Logger.log('Signature injected into PDF document successfully.');

      fs.writeFileSync('output-signed.pdf', signedPdfBytes);
      return signedPdfBytes;

    } catch (error) {
      Logger.error('Error signing document:', error.message);
      throw new Error(`Error signing document: ${error.message}`);
    }
  }  

    private createHashWith(buffer: Buffer): Buffer {
    const hash = createHash('sha256');
    hash.update(buffer);
    return hash.digest();
  }
import {Signer} from '@signpdf/signpdf'

class AzureVaultSigner extends Signer {
  signature: Buffer;
  constructor(signature: any) {
    super();
    this.signature = Buffer.from(signature);; // Store the signature
  }

  async sign(pdfBuffer, signingTime) {
    return pdfBuffer;
  }
}

export default AzureVaultSigner;

as i understand, Azures cryptoclient sign returns the signature it self, that later has to be injected in to original pdf. And i believe that issue is in my custom signer. and after running the api im getting this
image

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions