digitalbazaar / forge

A native implementation of TLS in Javascript and tools to write crypto-based and network-heavy webapps
https://digitalbazaar.com/
Other
5.06k stars 779 forks source link

unknown signature validity when signing pdfs #792

Open i-olivares opened 4 years ago

i-olivares commented 4 years ago

Hi,

I'm trying to develop an electronic signature module and I think I have almost succeded in it.... but It seems to be something i don't understand completely. Everything seems to work fine but when I open the pdf adobe says that "There are problems with the signature ". When I check whats happening inside the digital signature panel, It says: The signature validity is unknown - "the identity of the signer is unknown because it is not included in the list of trusted certificates and none of its main certificates are trusted certificates". Is this normal? What am I missing?

To create the .p12 file that i use to sign the pdf, I first create a CSR and include attributes, public key and sign with the private key created for the subject. Then I create another pair of keys as they were coming from a Certification authority ( I know, they don't, but is it possible to sign trustedly and create my own trusted signature? As if I were a trusted authority?), I create a certificate and set 'basicConstraints' with cA: true and 'keyUsage' and 'extKeyUsage' as said in https://github.com/digitalbazaar/forge/issues/57. The code I have used is shown below. I am a bit confused, could someone explain me how is this supposed to be done? Is it possible to trustedly sign pdfs in a browser? I also attach two images of the signed pdf (although they are in spanish... sorry) one before manual validation and another one after manual validation of the signature. Thanks in advance!!

var keys = forge.pki.rsa.generateKeyPair(2048); var csr = forge.pki.createCertificationRequest(); csr.publicKey = keys.publicKey; var attrsSubject = [{ name: 'commonName', value: name +' ' + family }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: '' }, { name: 'localityName', value: 'New York' }, { name: 'organizationName', value: 'organization' }, { shortName: 'OU', value: ' ' }]; csr.setSubject(attrsSubject)

// add optional attributes
/*csr.setAttributes([{
  name: 'challengePassword',
  value: 'password'
}, {
  name: 'unstructuredName',
  value: 'My company'
}]);*/

// sign certification request
csr.sign(keys.privateKey);
console.log('Certification request (CSR) created.');

console.log('Creating certificate...'); var cert = forge.pki.createCertificate(); var pair = forge.pki.rsa.generateKeyPair(2048);

//cert.publicKey = pair.publicKey; cert.serialNumber = '01'; cert.validity.notBefore = new Date(); cert.validity.notAfter = new Date(); cert.validity.notAfter.setFullYear(cert.validity.notBefore.getFullYear() + 1); cert.signatureOid = "1.2.840.113549.1.1.11"; cert.setSubject(csr.subject.attributes);

var attrsIssuer = [{ name: 'commonName', value: 'Biotype.co' }, { name: 'countryName', value: 'US' }, { shortName: 'ST', value: 'Virginia' }, { name: 'localityName', value: 'Blacksburg' }, { name: 'organizationName', value: 'Biotype' }, { shortName: 'OU', value: 'Biotype' }]; cert.setIssuer(attrsIssuer);

cert.setExtensions([{ name: 'basicConstraints', cA: true }, { name: 'keyUsage', keyCertSign: true, digitalSignature: true, nonRepudiation: true, keyEncipherment: true, dataEncipherment: true }, { name: 'subjectAltName', altNames: [{ type: 6, // URI value: 'http://biotype.co' }] },{ name: 'extKeyUsage', serverAuth: true, clientAuth: true, codeSigning: true, emailProtection: true, timeStamping: true }]); cert.publicKey = csr.publicKey; cert.sign(pair.privateKey,forge.md.sha256.create()); console.log('Certificate created.');

// create PKCS12 console.log('\nCreating PKCS#12...'); var password = 'password'; var newPkcs12Asn1 = forge.pkcs12.toPkcs12Asn1( keys.privateKey, [cert], password, {algorithm: '3des', generateLocalKeyId: true, friendlyName: 'test'}); var newPkcs12Der = forge.asn1.toDer(newPkcs12Asn1).getBytes();

image image

taxilian commented 4 years ago

The reason is that Adobe only trusts a certain list of CAs -- and those CAs have agreed to not issue any document signing certificates without locking them in hardware tokens, so you can't export it as a .p12 file.

Basically unless node-forge somehow starts supporting PKCS#11 hardware tokens you will never be able to use forge to sign a pdf and have it show up as green.

usimebul commented 4 years ago

If you want show your signature to be valid, you should add the generated self-signed certificate to trusted certificates on your local machine.

The warning on the Adobe PDF viewer means the the validity of certificate is unknown, not the signature. If the signature is invalid, then the Viewer shows an error.