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

Digital signatures in pdf.js #1076

Closed
soa-x opened this issue Jan 13, 2012 · 197 comments
Closed

Digital signatures in pdf.js #1076

soa-x opened this issue Jan 13, 2012 · 197 comments

Comments

@soa-x
Copy link

soa-x commented Jan 13, 2012

Hi! We are interested about when or if you´re going to implement the Signature Data View (Xades, Pades & Cades) in the PDF viewer (PDF.js)

Kind Regards

Alejandro Pinedo,
SOA-X

@brendandahl
Copy link
Contributor

There are currently no imminent plans to implement this feature. We haven't seen it come up much so it hasn't been a priority. We're always looking for more contributors though, so we'd welcome any patches to add this feature. If you're interested in adding it feel free to stop by our IRC channel(#pdfjs irc.mozilla.org) if you have questions.

Brendan

@fermo111
Copy link

Hi

what is the present state on the implementation of this feature?

Thanks

@yurydelendik
Copy link
Contributor

@fermo111 Not implemented yet, but I will be glad to coach somebody who is willing to take this task.

@wolvz
Copy link

wolvz commented Mar 31, 2014

@yurydelendik I'm interested in implementing the feature of presenting digital signatures of PDF files in pdf.js. How can I contact you?

@yurydelendik
Copy link
Contributor

@wolvz please find me at IRC irc.mozilla.org channel #pdfjs (that's simplest) or join any of our public meetings to coordinate stuff.

@wolvz
Copy link

wolvz commented May 31, 2014

I'm trying to implement SigWidgetAnnotation (like TextAnnotation, LinkAnnotation), in annotation.js, for supporting digital signatures in pdf.js.
The signature is showing up in the pdf viewer, and I already can extract and verify the certificates embbeded in the DER-encoded PKCS7 object...
Now I'm moving into the next step, which is to verify the message digest of the file.
For that I need to have access to the file contents... I dont' know if it's possible or not to have access to that from annotation.js, but I can't figure it out. The best I could do was to get the contents in core.js using:

var contentStreamPromise = this.pdfManager.ensure(this, 'getContentStream',[]);
var dataPromises = Promise.all([contentStreamPromise]);
dataPromises.then(function(data) {
var contentStream = data[0];
var contents = contentStream.str.bytes;
return contents;
});

Can someone please enlighten me on what is the best way to get file contents in annotation.js?
Thanks in advance...

@yurydelendik
Copy link
Contributor

@ashrafulkarim
Copy link

wolvz,
any progress in this regard?

@brendandahl brendandahl modified the milestones: 2014 Q3, 2014 Q4 Oct 2, 2014
@brendandahl brendandahl modified the milestone: 2014 Q4 Jan 8, 2015
@corynewey
Copy link

@yurydelendik @wolvz
I am extremely interested in the digital signature display feature. I cloned wolvz's repository and built the code but when I try to use it, I'm getting a promise rejection with this error: "require is not defined". Could anyone explain what would cause that error and how I could fix it? Also, I am very willing to continue the work on this feature. I've worked with pdf's in Java via the iText library but working with them in javascript is something I've never tried before. Could someone direct me to some documentation/tutorial that could get me pointed in the right direction so that I can figure out where to start as I try to move this feature further down the field?

@mrpandya007
Copy link

I am confused. What i have to do in my pdf.js library to show digital signature pdf in pdfJS

@mrpandya007
Copy link

untitled

This signature and certificate both showing in pdf.. but when i open it in pdf.js it wont showing there.

@wolvz
Copy link

wolvz commented Mar 18, 2015

@mrpandya007, the digital signature doesn't show because the developers chose to hide it until they have signature verification feature working.
If I recall, if you want them simply to show up you have to comment lines 389 to 392 here: https://github.com/mozilla/pdf.js/blob/master/src/core/annotation.js#L389
Not sure though, and I can't test it right now.

@mrpandya007
Copy link

@wolvz, Thanx for the response but its already commented. PLease look into this,, Crystal report's generated pdf signature is not showing but DevExpress generated pdf is showing it properly

@mrpandya007
Copy link

Please answer me .... what i have to do.. I can give you that pdf to test

@timvandermeij
Copy link
Contributor

There is no good support for digital signatures yet, so this will have to be implemented.

@mrpandya007
Copy link

How many days it will take to fix this problem of digital signature because we are dependent on your lib.

@timvandermeij
Copy link
Contributor

It might take a long time as this feature will have to be developed by someone and there are currently higher-priority issues.

@mrpandya007
Copy link

heading

Why i am facing such issue of "=" sign in Headings, only in pdf.js, after downloading the file it gone.
any solution please. It is happens only in telerik generated pdf.

@softboy99
Copy link

Hi,
I'm confused. Does this lib have api to digitally sign the pdf file? or we discussed here is just to show the signed pdf's digital signature?

@stephanrauh
Copy link

@softboy99 No, pdf.js doesn't have an API to sign a PDF file. And it doesn't display digital signatures because the team discovered it's difficult to verify the signature is valid. However, some people found out it's possible to display signatures nonetheless. What I'm interested in is the original idea: displaying valid, correctly signed signatures, and being able to detect fraud signatures. The code snippet provided by earthchie seems to point into this direction. But since I'm new to cryptography, I can't tell whether it can be used to verify the signature is valid. Does anybody following this discussion know?

@softboy99
Copy link

softboy99 commented Feb 8, 2021

Hi,
@stephanrauh, thanks for your clarifications, this issue has been opened almost 10 years. I suggests pdf.js should design this api because it is very important to many officialy published pdf files, otherwise, why the pdf is needed, they can use other file formats. We should use community power to do this. Suggest the following lib for refence:
https://github.com/Communication-Systems-Group/pdfsign.js
,which use forge lib for the cryptography.

@rmhrisk
Copy link

rmhrisk commented Feb 8, 2021

@softboy99 No, pdf.js doesn't have an API to sign a PDF file. And it doesn't display digital signatures because the team discovered it's difficult to verify the signature is valid. However, some people found out it's possible to display signatures nonetheless. What I'm interested in is the original idea: displaying valid, correctly signed signatures, and being able to detect fraud signatures. The code snippet provided by earthchie seems to point into this direction. But since I'm new to cryptography, I can't tell whether it can be used to verify the signature is valid. Does anybody following this discussion know?

We do both sign and verify with https://verify.ink

@softboy99
Copy link

Hi,
@rmhrisk, it is a cloud server side solution. Ther're many colud server side solution in the world. we discussed here is an client side solution.

@rmhrisk
Copy link

rmhrisk commented Feb 8, 2021

Hi,
@rmhrisk, it is a cloud server side solution. Ther're many colud server side solution in the world. we discussed here is an client side solution.

No, The document doesn’t leave the browser, the validation happens in browser, the signing happens in the browser, the encryption/decryption happens on the browser, the rendering happens in the browser, it’s all client side.

@softboy99
Copy link

Hi,
@rmhrisk, it is a cloud server side solution. Ther're many colud server side solution in the world. we discussed here is an client side solution.

No, The document doesn’t leave the browser, the validation happens in browser, the rendering happens in the browser, it’s all client side.

If your computer cannot connect to https://verify.ink/viewer, what will happen?

src="https://verify.ink/viewer?url={YOUR_DOCUMENT_URL}"

@rmhrisk
Copy link

rmhrisk commented Feb 8, 2021

Hi,
@rmhrisk, it is a cloud server side solution. Ther're many colud server side solution in the world. we discussed here is an client side solution.

No, The document doesn’t leave the browser, the validation happens in browser, the rendering happens in the browser, it’s all client side.

If your computer cannot connect to https://verify.ink/viewer, what will happen?

src="https://verify.ink/viewer?url={YOUR_DOCUMENT_URL}"

It’s possible to host the web component on ones own servers too.

@stephanrauh
Copy link

@softboy99 I'm not a member of the pdf.js team. I just maintain of fork of pdf.js for my own PDF viewer. However, what we can do is implement the feature in ngx-extended-pdf-viewer until it's mature. After that, we can offer the implementation to pdf.js. I can't do that alone (for lack of knowledge and lack of leisure time), so I'd appreciate help. Maybe even your help?

@earthchie
Copy link

@earthchie Your code snippet looks promising. Does it also verify the signature is valid?
(I'm new to cryptography, so I really don't know).

Sorry for the late reply.

The answer is no.
However, this might help you: https://github.com/MohammedEssehemy/node-sign-validate-pdf/blob/master/script.js#L338

If I understand correctly. There are two steps to verify a PDF signature.

  1. decrypt the signature message with a public key of the singer. you'll get the hash as a result.
  2. sha256 the PDF content, then compare with step 1. if two hashes match, the signature is valid.

but it is not as easy as it seems. In step 2, you'll need to slice some of the PDF content precisely, or else the hash will shift.
The start and end positions can be found in ByteRange on the 4th lines. This is very tricky and I still can't figure what I do wrong because I can't get the right hash yet.

Recently I also found a signed-PDF which signature is not in the 5-line format too. So the snippet I provided earlier might not work all the time.

Please try this instead. (I know, the code is a mess lol. Please forgive me.)

<form id="getPDFSignature">
    <input type="file" name="pdf" accept="application/pdf" required>
    <button>get Signatures</button>
</form>
document.getElementById('getPDFSignature').onsubmit = function (e) {
    e.preventDefault();

    let FR = new FileReader();
    FR.onload = function (e) {
        let Signatures = getPDFSignature(e.target.result);
        if(Signatures){
            console.log(Signatures);
        }else{
            alert('This document does not contains any signature.');
        }
    }
    FR.readAsText(this.pdf.files[0]);

    return false;
}

function getPDFSignature(pdf){
  return pdf.split(/endobj/).filter(l=>l.indexOf('adbe.pkcs7.detached')>-1).map(d=>{
      let sig = {};
      d = d.trim();
      let date = d.match(/\/M\(D:(.*?)\)/)[1].replace("'",'').match(/(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(.{5})/);
      let reason = d.match(/\/Reason\((.*?)\)\//);
      let location = d.match(/\/Location\((.*?)\)\//);
      sig.raw = d;
      sig.header = d.match(/(\d) (\d) obj/)[0];
      sig.ByteRange = d.match(/\/ByteRange.*?\[(.*?)\]/)[1].trim().split(' ').map(i=>+i);
      sig.Date = new Date(`${date[1]}-${date[2]}-${date[3]}T${date[4]}:${date[5]}:${date[6]}${date[7]}`);
      sig.Contents = d.match(/\/Contents *?\<(.*?)\>/)[1].replace(/(?:00)*$/, '');
      sig.Signature = {Der: hex2str(sig.Contents)};
      sig.Signature.ASN1 = forge.asn1.fromDer(sig.Signature.Der);
      sig.Signature.message = forge.pkcs7.messageFromAsn1(sig.Signature.ASN1);
  
      if(reason){
          sig.Reason = reason[1];
      }else{
          sig.Reason = '';
      }
      if(location){
          sig.Location = location[1];
      }else{
          sig.Location = '';
      }
      
      return sig;
  });
}

function hex2str(str1){
	var hex  = str1.toString();
	var str = '';
	for (var n = 0; n < hex.length; n += 2) {
		str += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
	}
	return str;
}

Will update ya later once I successfully validate the signature with PDF content.

@marco-c
Copy link
Contributor

marco-c commented Apr 22, 2021

We are now displaying signatures (#13214), but we are not validating them yet.

@timvandermeij
Copy link
Contributor

Closing since digital signatures are now displayed. Validation is tracked in issue #13351 now because this thread has become very large and hard to keep track of.

@kjhangiani
Copy link

@timvandermeij do you know which version specifically pdfjs started displaying digital signatures? We are currently still using a forked version with the code snippets in this thread to display them in our app - it would be nice to switch back to mainline. I tried scouring the releases and this thread but I do not see the related PR.

Thanks!

@timvandermeij
Copy link
Contributor

The PR is #13214 and it's released yet.

@mayconmarchiori

This comment has been minimized.

@sylvestre
Copy link
Contributor

@soa-x Sorry but who is "We" in comment #0 ? :)
And what is your use case?
Thanks

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

No branches or pull requests