Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
arvydas-kezunas opened this issue Sep 20, 2024 · 4 comments

Comments

@arvydas-kezunas
Copy link

arvydas-kezunas commented Sep 20, 2024

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: '[email protected]',
        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

@dhensby
Copy link
Collaborator

dhensby commented Sep 20, 2024

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;

You're just returning the PDF in your signer and not the signature. If you change that, it may work

@arvydas-kezunas
Copy link
Author

i will check that

@arvydas-kezunas
Copy link
Author

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;

You're just returning the PDF in your signer and not the signature. If you change that, it may work

Maybe you have idea where i could fine example of custom signer that would work with my issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
@dhensby @arvydas-kezunas and others