Hello
I have some problem with custom signing in Reactjs and Nodejs. After signing, I see the notify ‘The digest is incorrect’.Anyone that could help? Thank you!
Frontend
const signDocumentWithOTP = async () => {
const { PDFNet, documentViewer } = instance.Core
const doc = await documentViewer.getDocument().getPDFDoc()
// Get signature field for signing
const field = await doc.getField(fieldName)
const signatureField = await PDFNet.DigitalSignatureField.createFromField(field)
// Create a digital signature dictionary inside the digital signature field
await signatureField.createSigDictForCustomSigning(
'Adobe.PPKLite',
PDFNet.DigitalSignatureField.SubFilterType.e_adbe_pkcs7_detached,
7500,
)
const currentTime = new PDFNet.Date()
await currentTime.setCurrentTime()
await signatureField.setSigDictTimeOfSigning(currentTime)
await doc.saveMemoryBuffer(PDFNet.SDFDoc.SaveOptions.e_incremental)
const pdf_digest = await signatureField.calculateDigest(PDFNet.DigestAlgorithm.Type.e_SHA256)
const signedAttrs = await PDFNet.DigitalSignatureField.generateCMSSignedAttributes(pdf_digest)
console.log(signedAttrs)
// Get certificate
const res = await fetch('http://localhost:8000/sign/signData', {
method: 'POST',
body: JSON.stringify({email: user.email, data: signedAttrs}),
headers: {
"Accept": "application/json",
"Content-Type": "application/json"
}
}).then(res => res.json()).then(async (res) => {
if(res.success) {
console.log(res.signature)
const signature_value = new Uint8Array(Object.values(res.signature))
const cert = base642arr(res.certificate);
const signer_cert = await PDFNet.X509Certificate.createFromBuffer(cert)
const chain_cert = [signer_cert]
const digest_algorithm_oid = await PDFNet.ObjectIdentifier.createFromDigestAlgorithm(PDFNet.DigestAlgorithm.Type.e_SHA256)
const signature_algorithm_oid = await PDFNet.ObjectIdentifier.createFromIntArray([1,2,840,113549,1,1])
const cms_signature = await PDFNet.DigitalSignatureField.generateCMSSignature(
signer_cert,
chain_cert,
digest_algorithm_oid,
signature_algorithm_oid,
signature_value,
signedAttrs
)
await doc.saveCustomSignatureBuffer(cms_signature, signatureField)
}
})
}
- Backend
exports.signData = async (req, res, next) => {
try {
const {email, data} = req.body;
const p12FilePath = './files/' + email + '.p12'
const p12Asn1 = forge.asn1.fromDer(fs.readFileSync(p12FilePath, 'binary'));
const p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1, false, 'ejbca');
let certificate;
let certificates = []
for (const safeContents of p12.safeContents) {
for (const safeBag of safeContents.safeBags) {
if (safeBag.type === forge.pki.oids.certBag) {
certificates.push(safeBag.cert);
}
}
}
const privateKey = fs.readFileSync('./files/privatekey.key')
const publicKey = forge.pki.setRsaPublicKey(privateKey.n, privateKey.e);
// Get certificate
certificate = certificates[0];
const derBytes = forge.asn1.toDer(forge.pki.certificateToAsn1(certificate)).getBytes();
const base64Cert = forge.util.encode64(derBytes);
// Sign data
const uint8Array = new Uint8Array(Object.values(data));
const signature = crypto.sign("SHA256", uint8Array, privateKey);
const signature_value = new Uint8Array(signature)
console.log(typeof signature_value, signature_value)
res.json({success: true, signature: signature_value, certificate: base64Cert});
} catch (error) {
console.error(error);
res.status(500).json({success: false, message: 'Server Error'});
}
}