Цифровая подпись PDFNet в Node JS с использованием Google KMS

Я видел пример подписания https://www.pdftron.com/documentation/nodejs/guides/features/signature/sign-pdf

signOnNextSave использует сертификат PKCS #12, но я использую Google KMS для асимметричной подписи, чтобы обеспечить безопасность закрытых ключей.

Вот пример подписи и проверки с помощью Google Cloud KMS.

Я пытался реализовать собственный SignatureHandler, но Node.JS API отличается от Java или .NET https://www.pdftron.com/api/pdfnet-node/PDFNet.SignatureHandler.html

Как я могу реализовать пользовательскую логику подписи и проверки?

const data = Buffer.from('pdf data')

// We have 2048 Bit RSA - PSS Padding - SHA256 Digest key in Google Cloud KMS
const signAsymmetric = async () => {
  const hash = crypto.createHash('sha256')
  hash.update(data)
  const digest = hash.digest()
  const digestCrc32c = crc32c.calculate(digest)

  // Sign the data with Cloud KMS
  const [signResponse] = await client.asymmetricSign({
    name: locationName,
    digest: {
      sha256: digest
    },
    digestCrc32c: {
      value: digestCrc32c
    }
  })

  if (signResponse.name !== locationName) {
    throw new Error('AsymmetricSign: request corrupted in-transit')
  }
  if (!signResponse.verifiedDigestCrc32c) {
    throw new Error('AsymmetricSign: request corrupted in-transit')
  }
  if (
    crc32c.calculate(signResponse.signature) !==
    Number(signResponse.signatureCrc32c.value)
  ) {
    throw new Error('AsymmetricSign: response corrupted in-transit')
  }

  // Returns signature which is buffer
  const encoded = signResponse.signature.toString('base64')
  console.log(`Signature: ${encoded}`)

  return signResponse.signature
}

// Verify data with public key
const verifyAsymmetricSignatureRsa = async () => {
  const signatureBuffer = await signAsymmetric()
  const publicKeyPem = await getPublicKey()

  const verify = crypto.createVerify('sha256')
  verify.update(data)
  verify.end()

  const key = {
    key: publicKeyPem,
    padding: crypto.constants.RSA_PKCS1_PSS_PADDING
  }

  // Verify the signature using the public key
  const verified = verify.verify(key, signatureBuffer)
  return verified
}

person Mirian Okradze    schedule 22.02.2021    source источник


Ответы (1)


В настоящее время PDFTron SDK поддерживает только пользовательские обработчики на C++, Java и C# (в будущем планируется включить дополнительные языки).

На другой платформе, такой как C++, вы бы расширили пользовательские функции обработчика, поместив hash.update(data) в SignatureHandler::AppendData, а остальная часть signAsymmetric перешла бы в SignatureHandler::CreateSignature. Пользовательскому обработчику для совместимости будет присвоено имя, например Adobe.PPKLite (мы пока не поддерживаем записи SubFilter пользовательского обработчика, только фильтр — см. стандарт PDF для разницы — но это не будет иметь значения, пока вы используете инструмент проверки который поддерживает фильтр Adobe.PPKLite). Конкретный пример см. по следующей ссылке: https://www.pdftron.com/documentation/samples/cpp/DigitalSignaturesTest

Что касается проверки, наш код уже может сделать это за вас, если ваши подписи соответствуют следующим условиям:

  1. они используют стандартный алгоритм дайджеста
  2. они используют RSA для подписи
  3. они используют правильные форматы данных в соответствии со стандартом PDF (например, отдельная CMS, словарь цифровых подписей)

Если у вас есть дополнительные вопросы или вам нужна дополнительная информация, обращайтесь в службу поддержки PDFTron по адресу [email protected].

person Shakthi Wijeratne    schedule 23.02.2021
comment
Метод createSignature в классе SignatureHandler вызывается дважды после вызова метода сохранения в документе PDF. Это нормально? - person Mirian Okradze; 26.02.2021