Discussion:
[iText-questions] Sign and PDF with SmartCard and web browser only
madmax
2012-01-22 22:32:44 UTC
Permalink
I am in need for some guidance. I have a scenario where I am required to
sign PDFs using a smartcard. The catch is that it needs to be done on a
server (Jboss) and the only interaction allowed is via a web browser
(Microsoft IE). I found several threads but I am unable to put it all
together for a final solution. This is way out of my comfort zone and I
have just started learning this.

In my first design I was hoping to leverage access of the smartcard private
key using the ActiveX CAPICOM but that proved useless. I suspect there is
some type of mechanisms that prevents me to do that otherwise it would be
too easy. Although I was able to display what appears to be a key in the
browser using Signer.Certificate.PrivateKey.

This is my second design after the first one crashed and burned:

1) The user interacts with IE and selects the PDF that need to signed
(The PDFs are stored in SQL server). The process in initiated by the user
via an AJAX call



2) The Java servlet receives the AJAX call and requests the PDF from
the SQL server and uses iText to begin the process of signing the document.
Here are some high-level steps (based on examples form itext and the
forums but the main inspiration was from
http://itext-general.2136553.n4.nabble.com/HASH-SMARTCARD-and-PKCS-7-detached-td3047252.html
)

a. creates a PdfStamper,

b. uses the setExternaldigest

c. preCloses the stamper

d. creates digest and sends it back to the browser via AJAX

e. Place the PdfStampre object in session so that it can be reused for
the final step



3) The client browser receives the digest and uses the internal
CAPICOM ActiveX control using javascript (
ActiveXObject("CAPICOM.SignedData") ) ) Idea came from
http://bozhobg.wordpress.com/2009/04/16/how-to-create-a-digital-signing-solution-with-only-javascript/

a. The user is asked via the browser to enter their smartcarcd and
their pin

b. Set the digest that came from the server to the SignedData.Content
of the activex

c. Call the CAPICOM activex SignedData.Sign(Signer, false,
CAPICOM_ENCODE_BASE64) which returns the signed hash

d. Return he signed hash to the server to sign the PDF via another
AJAX call



4) This is where things break down I cannot figure what I should do
next

a. I have the signed hash

b. I convert it to byte[] data =
Base64.decodeBase64(signedHash.trim().getBytes());

c. I get the PdfSamper back from session

d. I invoke PdfSigGenericPKCS sg = appearance.getSigStandard() but
it’sNULL.

Now I am not sure if this is even possible or what I am doing wrong. I also
saw a c# example that addressed the smartcard but I was not able to fully
comprehend and could not find and equivalent in Java since it was using the
.net framework.

Has anyone solved this type of problem with just Java, a browser and some
server side code? Sample code or ideas would be greatly appreciated?



Thanks in advance

max


--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4319344.html
Sent from the iText - General mailing list archive at Nabble.com.
wang31894
2012-01-23 14:35:19 UTC
Permalink
Interesting, I am having some similar issues with your case, can some help
us? Many Thanks

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4320859.html
Sent from the iText - General mailing list archive at Nabble.com.
madmax
2012-01-24 13:32:30 UTC
Permalink
So is tinkered with it a little more and I was able to somewhat sign the PDF.
Bu things are never as simple as we would like them to be. I can see the
signature on a separate page but when I try to validate it acrobat it
returns the following error:


Error during signature verification. Error encountered while validating:
Internal cryptographic library error. Error Code: 0x2726


When I try to look at the signature via the “signature panel” it says “an
error occurred while attempting to validate the signature”


I tried to goggle for a clue but I had no luck so far. Could any of the
experts provide some guidance, ideas?


Thanks again


max


--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4323750.html
Sent from the iText - General mailing list archive at Nabble.com.
mkl
2012-01-27 15:21:50 UTC
Permalink
max,
Hi Guys, please help? or we should try other forums? Any help is greatly
appreciated. thx
Maybe you simply didn't give us the information required. First you give
some implementation ideas (item 1 through 3 of your list), but then in your
item 4c you say
I invoke PdfSigGenericPKCS sg = appearance.getSigStandard() but it’sNULL.
which is an issue description on the code level.

As it depends on the prior code details whether or not SigStandard is set,
we need some code to help you. Obviously, though, the code of your whole
construct is too much. Thus, reduce it to a simple failing sample and
probably we can help. Or, of course, you locate the culprit yourself during
simplification...

Regards, Michael

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4333781.html
Sent from the iText - General mailing list archive at Nabble.com.
madmax
2012-01-30 12:26:27 UTC
Permalink
Hi Michael my apologize I was trying to avoid dumping a bunch of code and
turning everyone off but you are right with no code it’s kind of hard to get
help or direction. So here is some code fragments, there is aJSP, the
CAPICOM activex control and a servlet.

*Step 1:
JSP makes an AJAX call to servlet
HTML/Javascript Fragments*

*Step 2:
Servlet is invoked by ajax call to get the PDF digest*
private String getDigest(String path, String fileName,
HttpServletRequest request) {
HttpSession session = request.getSession();
log.info("getDigest (begin)...");

try {
//1. Convert cert chain string to certificate class
SHA256withRSA
String myChain = "-----BEGIN CERTIFICATE----- MIIG6DCCBdCgAwIBAgICAZowDQ
........ -----END CERTIFICATE-----";
Certificate[] certChain = {getCertificate(myChain)};

//2.Initialize reader, stamper.
PdfReader reader = new PdfReader(path + "/" + fileName);
int page = reader.getNumberOfPages() + 1;
PdfStamper stamper = PdfStamper.createSignature(reader, new
FileOutputStream(OUT_DIR + fileName), '\0');
PdfSignatureAppearance appearance =
stamper.getSignatureAppearance();

//3.Configure SignatureAppearance
appearance.setSignDate(new GregorianCalendar());
appearance.setCrypto(null, certChain, null,
PdfSignatureAppearance.WINCER_SIGNED);
appearance.setReason("Digitally Signed");
appearance.setLocation("Some Place");
appearance.setContact("madmax");
appearance.setAcro6Layers(true);
appearance.setSignatureGraphic(Image.getInstance(SIG_DIR +
"/madmax-sig.jpg"));

appearance.setRenderingMode(PdfSignatureAppearance.RenderingMode.GRAPHIC_AND_DESCRIPTION);


stamper.insertPage(page, new Rectangle (160,732, 232, 780));
appearance.setVisibleSignature(new Rectangle (160,732, 232,
780), page, "my_sig");
appearance.setExternalDigest(new byte[513], new byte[20],
"RSA");

//4. Create signature dictionary
PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKMS,
PdfName.ADBE_PKCS7_DETACHED);

dic.setName(PdfPKCS7.getSubjectFields((X509Certificate)certChain[0]).getField("CN"));
if (appearance.getSignDate()!= null) dic.setDate(new
PdfDate(appearance.getSignDate()));
if (appearance.getReason()!= null)
dic.setReason(appearance.getReason());
if (appearance.getLocation() != null)
dic.setLocation(appearance.getLocation());
if (appearance.getContact() != null)
dic.setContact(appearance.getContact());
appearance.setCryptoDictionary(dic);

//5. Reserve space for CONTENTS
int csize = 15000;
HashMap<PdfName, Integer> exc = new HashMap();
exc.put(PdfName.CONTENTS, csize * 2 + 2);
appearance.preClose(exc);

//6. Calculate content stream digest
MessageDigest messageDigest =
MessageDigest.getInstance("SHA-256");
byte buf[] = new byte[8192];
int n;
InputStream inp = appearance.getRangeStream();

while ((n = inp.read(buf)) > 0) {
messageDigest.update(buf, 0, n);
}

byte hash[] = messageDigest.digest();
session.setAttribute("stamper", stamper);
session.setAttribute("hash", new String(hash));

log.info("getDigest (end)...");
return new String(hash);
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
catch (DocumentException e) {
e.printStackTrace();
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}

log.info("getDigest (end)...");
return null;
}

*Step 3:
The digest is returned to the JSP Servlet and calls the CAPICOM activex
control and call the "SignedData" method it is then rturn to the servlet a
second time
which call this metgoe to finalize the signature*

private void signPdf(String path, String fileName, String digest,
HttpServletRequest request) {
HttpSession session = request.getSession();
stamper = (PdfStamper) session.getAttribute("stamper");
appearance = stamper.getSignatureAppearance();

//1. Convert cert chain string to certificate class SHA256withRSA
String myChain = "-----BEGIN CERTIFICATE-----
MIIG6DCCBdCgAwIBAgICAZowDQ ........ -----END CERTIFICATE-----";
Certificate[] certChain = {getCertificate(myChain)};

PdfStamper stamper;
PdfSignatureAppearance appearance;
PdfDictionary dic = appearance.getCryptoDictionary();

//1. Sign the PDF
byte[] hash = ((String) session.getAttribute("hash")).getBytes();
log.info("signPdf with Digest (begin)...");
try {
byte[] data = Base64.decodeBase64(digest.trim().getBytes());
log.info(">> " + digest.length());

Calendar cal = appearance.getSignDate();
byte[] ocsp = null;

PdfPKCS7 sig = new PdfPKCS7(null, certChain, null, "SHA-256",
null, false);
sig.setExternalDigest(hash, data, "RSA");

PdfLiteral pdfLiteral = (PdfLiteral) dic.get(PdfName.CONTENTS);
byte[] outc = new byte[(pdfLiteral.getPosLength() - 2) / 2];

byte[] ssig = sig.getEncodedPKCS7(null, cal, null, ocsp);
Arrays.fill(outc,(byte)0);
System.arraycopy(ssig, 0, outc, 0, ssig.length);
PdfDictionary dic2 = new PdfDictionary();
dic2.put(PdfName.CONTENTS, new
PdfString(outc).setHexWriting(true));
appearance.close(dic2);
}

catch (IOException e) {
e.printStackTrace();
}
catch (DocumentException e) {
e.printStackTrace();
}
catch (Exception e) {

e.printStackTrace();
}
log.info("signPdf with Digest (end)...");

}

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4340836.html
Sent from the iText - General mailing list archive at Nabble.com.
mkl
2012-01-30 15:49:05 UTC
Permalink
max,
Post by madmax
Hi Michael my apologize I was trying to avoid dumping a bunch of code and
turning everyone off but you are right with no code it’s kind of hard to
get help or direction. So here is some code fragments, there is aJSP, the
CAPICOM activex control and a servlet.
Good. I'm missing the code, though, in which you according to your initial
posting "invoke PdfSigGenericPKCS sg = appearance.getSigStandard() but
it’sNULL."
Post by madmax
Servlet is invoked by ajax call to get the PDF digest*
[...]
//4. Create signature dictionary
PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKMS,
PdfName.ADBE_PKCS7_DETACHED);
dic.setName(PdfPKCS7.getSubjectFields((X509Certificate)certChain[0]).getField("CN"));
if (appearance.getSignDate()!= null) dic.setDate(new
PdfDate(appearance.getSignDate()));
if (appearance.getReason()!= null)
dic.setReason(appearance.getReason());
if (appearance.getLocation() != null)
dic.setLocation(appearance.getLocation());
if (appearance.getContact() != null)
dic.setContact(appearance.getContact());
appearance.setCryptoDictionary(dic);
SigStandard is only set to a non-null value during preClose() if
CryptoDictionary is null. Therefore, you "invoke PdfSigGenericPKCS sg =
appearance.getSigStandard() but it’sNULL."

Regards, Michael

PS: This has been discussed here quite recently, cf.
http://itext-general.2136553.n4.nabble.com/sap-SigStandard-Signer-is-null-tp4310088p4312763.html

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4341353.html
Sent from the iText - General mailing list archive at Nabble.com.
madmax
2012-01-31 03:55:13 UTC
Permalink
Michael,

I am no longer invoking that line of code at the time I was just trying to
kind of debug the problem and understand what might be going on..

The code fragments that I posted actually put a signature on the PDF but now
I have a problem when I open the PDF and try to verify the signature I get
this error from adobe

*Error during signature verification. Error encountered while validating:
Internal cryptographic library error. Error Code: 0x2726*

See attached screen shots of what I see when I try to verify a the signature
via adobe

Does this make sense? Any ideas? Sorry to continue to pester you but I am
clueless a this point.

Regards,
max
Loading Image...
1-30-2012_22-50-28.png
Loading Image...
1-30-2012_22-52-07.png

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4343448.html
Sent from the iText - General mailing list archive at Nabble.com.
mkl
2012-01-31 06:42:50 UTC
Permalink
Max,
The code fragments that I posted actually puts a signature on the PDF but
now I have a problem when I open the PDF and try to verify the signature I
get this error from adobe
Internal cryptographic library error. Error Code: 0x2726*
In that case please also supply a sample pdf signed by your code. It is
almost always easiest to analyse such problems by looking at the output
first.

Regards, michael

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4343645.html
Sent from the iText - General mailing list archive at Nabble.com.
Raffaele
2012-01-31 09:46:09 UTC
Permalink
Hi mkl,
i've the same problem with te error 0x2726 when open the PDF File.

Any suggestion??

THX in advance

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4343964.html
Sent from the iText - General mailing list archive at Nabble.com.
mkl
2012-01-31 10:03:32 UTC
Permalink
Raffaele,
Post by Raffaele
i've the same problem with te error 0x2726 when open the PDF File.
Any suggestion??
In that case please also supply a sample pdf signed by your code. It is
almost always easiest to analyse such problems by looking at the output
first.
Regards, Michael

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4344001.html
Sent from the iText - General mailing list archive at Nabble.com.
madmax
2012-01-31 12:59:56 UTC
Permalink
Post by mkl
Max,
The code fragments that I posted actually puts a signature on the PDF but
now I have a problem when I open the PDF and try to verify the signature
I get this error from adobe
Internal cryptographic library error. Error Code: 0x2726*
In that case please also supply a sample pdf signed by your code. It is
almost always easiest to analyse such problems by looking at the output
first.
Regards, michael
Hi Michael,

I am attaching the the signed PDF as well as the Java and JSP code and
lastly I made a recording on how it runs within internet explorer.

Thanks again for your time and suggestions.

max
http://itext-general.2136553.n4.nabble.com/file/n4344394/sample-1.pdf
sample-1.pdf
http://itext-general.2136553.n4.nabble.com/file/n4344394/x509ExternalSig.jsp
x509ExternalSig.jsp
http://itext-general.2136553.n4.nabble.com/file/n4344394/X509ServletExternalSignature.java
X509ServletExternalSignature.java
http://itext-general.2136553.n4.nabble.com/file/n4344394/capture-2.swf
capture-2.swf

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4344394.html
Sent from the iText - General mailing list archive at Nabble.com.
mkl
2012-01-31 16:33:53 UTC
Permalink
Max,
I am attaching the the signed PDF as well as the full Java and JSP code
and lastly I made a recording on how it runs within internet explorer
showing the interaction with the smartcard, servlet and itext.
http://itext-general.2136553.n4.nabble.com/file/n4344394/sample-1.pdf
Hhmmm, this one might be of interest for Leonard, too --- after a first
inspection the signature looks ok to me.

Well, yes, it does not contain any signed attributes, not even an ESS
signing certificate attribute. Therefore, this signature doesn't stand a
chance to fulfil any decent signature profile. But as a minimalist CMS
signature it looks ok.

Regards, Michael

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4345021.html
Sent from the iText - General mailing list archive at Nabble.com.
Keith O
2012-01-30 17:51:37 UTC
Permalink
Hi max,
Post by madmax
Now I am not sure if this is even possible or what I am doing wrong. I also
saw a c# example that addressed the smartcard but I was not able to fully
comprehend and could not find and equivalent in Java since it was using the
.net framework.
Would you share the link to the c# example?

thanks - keith
madmax
2012-01-31 03:13:57 UTC
Permalink
Hey Keith here are the c# examples I found that I was refering about in the
post

http://itextpdf.sourceforge.net/howtosign.html#signextitextsharp1

max


--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4343392.html
Sent from the iText - General mailing list archive at Nabble.com.
Keith O
2012-01-31 11:57:42 UTC
Permalink
Hi max,
Hey Keith here are the c# examples I found  that I was refering about in the
post
http://itextpdf.sourceforge.net/howtosign.html#signextitextsharp1
Thanks, I've seen that t you had found something else. Thank you for
the JavaScript links :)
Leonard Rosenthol
2012-01-31 16:42:54 UTC
Permalink
Yes, we do indeed fail validation. Just not enough here to do anything
useful.

Leonard
Post by mkl
Max,
I am attaching the the signed PDF as well as the full Java and JSP code
and lastly I made a recording on how it runs within internet explorer
showing the interaction with the smartcard, servlet and itext.
http://itext-general.2136553.n4.nabble.com/file/n4344394/sample-1.pdf
Hhmmm, this one might be of interest for Leonard, too --- after a first
inspection the signature looks ok to me.
Well, yes, it does not contain any signed attributes, not even an ESS
signing certificate attribute. Therefore, this signature doesn't stand a
chance to fulfil any decent signature profile. But as a minimalist CMS
signature it looks ok.
Regards, Michael
--
http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and
-web-browser-only-tp4319344p4345021.html
Sent from the iText - General mailing list archive at Nabble.com.
--------------------------------------------------------------------------
----
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
iText-questions mailing list
https://lists.sourceforge.net/lists/listinfo/itext-questions
iText(R) is a registered trademark of 1T3XT BVBA.
Many questions posted to this list can (and will) be answered with a
reference to the iText book: http://www.itextpdf.com/book/
http://itextpdf.com/themes/keywords.php
Andreas Kuehne
2012-01-31 19:12:46 UTC
Permalink
For curiosity I took a look at the signature, too. Here's what I got:

2012-01-31 20:04:13,281 ERROR (http-0.0.0.0-8080-7)
[de.trustable.signingserver.Verifier] Signature ERROR from signer # 0 :
javax.crypto.BadPaddingException: Invalid PKCS#1 padding: encrypted
message and modulus lengths do not match!

The decrypted signature content difinitly doesn't look like having a
padding applied:

2012-01-31 20:04:13,281 DEBUG (http-0.0.0.0-8080-7)
[de.trustable.signingserver.Verifier] unpadded decrypted
1a:e3:f9:19:c4:31:7d:9c:90:6e:0a:f3:a1:23:79:db:25:47:36:80:d6:a7:da:50:09:97:cb:ad:ab:a9:50:66:21:c0:84:f5:20:97:1e:0c:f1:40:ef:5f:58:d5:05:1a:f3:50:60:93:d6:8e:3c:78:9a:e1:fa:5b:a0:93:0f:f5:04:ef:e1:6b:43:63:27:0e:f0:c3:94:d7:9f:bf:3c:29:91:1c:f2:91:a6:7c:b0:56:b3:66:20:c2:45:80:d9:d4:c6:c1:f1:1f:c1:ab:13:ee:9e:6b:84:fe:54:2d:b4:83:61:5c:0a:43:92:28:35:d1:2f:76:ad:ed:28:89:ba:49:18:dd:88:a9:a5:89:7e:2c:cf:e4:f9:17:68:db:20:f4:c4:65:16:f6:ef:15:e5:8e:75:2d:7c:87:43:00:3d:aa:05:5a:30:50:38:0e:96:9f:4d:29:d1:1b:d9:4d:12:42:0e:f8:88:fa:40:90:a8:15:cd:46:37:bb:58:51:54:08:d1:e6:85:dc:75:f9:fb:b2:4a:d6:2d:94:54:ec:57:2b:43:8f:56:10:ac:84:eb:ce:e2:99:e7:0d:68:2c:29:c0:92:95:14:bf:fb:e4:5d:db:2f:6e:4a:dd:34:51:21:b8:6f:80:a1:0f:78:f2:8d:19:5c:99:3c:0c:cb:e1:fb:e3:

This problem usually stems from unmatching signing keys / certificates.
Up tol this point no details of the signature (signed attributes ...)
are relevant.

Greetings

Andreas K.
Post by Leonard Rosenthol
Yes, we do indeed fail validation. Just not enough here to do anything
useful.
Leonard
Post by mkl
Max,
I am attaching the the signed PDF as well as the full Java and JSP code
and lastly I made a recording on how it runs within internet explorer
showing the interaction with the smartcard, servlet and itext.
http://itext-general.2136553.n4.nabble.com/file/n4344394/sample-1.pdf
Hhmmm, this one might be of interest for Leonard, too --- after a first
inspection the signature looks ok to me.
Well, yes, it does not contain any signed attributes, not even an ESS
signing certificate attribute. Therefore, this signature doesn't stand a
chance to fulfil any decent signature profile. But as a minimalist CMS
signature it looks ok.
Regards, Michael
--
http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and
-web-browser-only-tp4319344p4345021.html
Sent from the iText - General mailing list archive at Nabble.com.
--------------------------------------------------------------------------
----
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
iText-questions mailing list
https://lists.sourceforge.net/lists/listinfo/itext-questions
iText(R) is a registered trademark of 1T3XT BVBA.
Many questions posted to this list can (and will) be answered with a
reference to the iText book: http://www.itextpdf.com/book/
http://itextpdf.com/themes/keywords.php
------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
iText-questions mailing list
https://lists.sourceforge.net/lists/listinfo/itext-questions
iText(R) is a registered trademark of 1T3XT BVBA.
Many questions posted to this list can (and will) be answered with a reference to the iText book: http://www.itextpdf.com/book/
Please check the keywords list before you ask for examples: http://itextpdf.com/themes/keywords.php
--
Andreas Kühne
phone: +49 177 293 24 97
mailto: ***@trustable.de

Trustable Ltd. Niederlassung Deutschland Ströverstr. 18 - 59427 Unna Amtsgericht Hamm HRB 5868

Directors Andreas Kühne, Heiko Veit

Company UK Company No: 5218868 Registered in England and Wales
mkl
2012-02-01 09:26:51 UTC
Permalink
Andreas, Max,
Post by Andreas Kuehne
2012-01-31 20:04:13,281 ERROR (http-0.0.0.0-8080-7)
javax.crypto.BadPaddingException: Invalid PKCS#1 padding: encrypted
message and modulus lengths do not match!
Oops, you're right of course. I didn't look into the logs here as I got back
a report complaining about the untrusted root and, falsely, deduced that
everything (including the signature) could be properly decoded. In the logs
I now also find

javax.crypto.BadPaddingException: Data must start with zero
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:308)
at ...
Post by Andreas Kuehne
The decrypted signature content difinitly doesn't look like having a
padding applied: This problem usually stems from unmatching signing keys /
certificates.
Max uses the iText utility class PdfPKCS7:

PdfPKCS7 sig = new PdfPKCS7(null, certChain, null, "SHA-256",
null, false);
sig.setExternalDigest(hash, data, "RSA");
[...]
byte[] ssig = sig.getEncodedPKCS7(null, cal, null, ocsp);

To create his data he uses

var SignedData = new ActiveXObject("CAPICOM.SignedData");
SignedData.Content = src;
var Signer = FindCertificateByHash();
[...]
Signer.AuthenticatedAttributes.Add(TimeAttribute);
var szSignature = SignedData.Sign(Signer, false,
CAPICOM_ENCODE_BASE64);

As I don't use these classes myself, I don't know whether this usage is
correct nor do I know the format of the input or output data.

If wild guesses are allowed, though, adding some "TimeAttribute" to those
"Signer.AuthenticatedAttributes" might imply that "szSignature" not merely
contains some PKCS#1 signature to include into a signature container by
means of the iText PdfPKCS7 utility class but instead already a full-blown
CMS signature container which can be inserted into the PDF as is.

Can anyone deny or confirm?

Regards, Michael

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4347309.html
Sent from the iText - General mailing list archive at Nabble.com.
Andreas Kuehne
2012-02-02 17:32:50 UTC
Permalink
Hi Michael,

the most interesting topic with this signature is the reaction of th
Adobe reader. Never seen such a kind of error message before!

But back to the signature problem itself: My wild guess is that the
ActiveXObject signs with one key but the signature contain s another
one. The usual smartcard today hosts a bunch of different certificates
and keypairs. The API will know which key/certificate to select for
signing but if you call 'getCrertificates' (or the like) the appropriate
certificate mustn't be the first one ...

Did you try to verify the signature within the signing code? If it
verifies, you're sure to have the right certificate selected.

Greeting

Andreas
Post by mkl
Andreas, Max,
Post by Andreas Kuehne
2012-01-31 20:04:13,281 ERROR (http-0.0.0.0-8080-7)
javax.crypto.BadPaddingException: Invalid PKCS#1 padding: encrypted
message and modulus lengths do not match!
Oops, you're right of course. I didn't look into the logs here as I got back
a report complaining about the untrusted root and, falsely, deduced that
everything (including the signature) could be properly decoded. In the logs
I now also find
javax.crypto.BadPaddingException: Data must start with zero
at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:308)
at ...
Post by Andreas Kuehne
The decrypted signature content difinitly doesn't look like having a
padding applied: This problem usually stems from unmatching signing keys /
certificates.
PdfPKCS7 sig = new PdfPKCS7(null, certChain, null, "SHA-256",
null, false);
sig.setExternalDigest(hash, data, "RSA");
[...]
byte[] ssig = sig.getEncodedPKCS7(null, cal, null, ocsp);
To create his data he uses
var SignedData = new ActiveXObject("CAPICOM.SignedData");
SignedData.Content = src;
var Signer = FindCertificateByHash();
[...]
Signer.AuthenticatedAttributes.Add(TimeAttribute);
var szSignature = SignedData.Sign(Signer, false,
CAPICOM_ENCODE_BASE64);
As I don't use these classes myself, I don't know whether this usage is
correct nor do I know the format of the input or output data.
If wild guesses are allowed, though, adding some "TimeAttribute" to those
"Signer.AuthenticatedAttributes" might imply that "szSignature" not merely
contains some PKCS#1 signature to include into a signature container by
means of the iText PdfPKCS7 utility class but instead already a full-blown
CMS signature container which can be inserted into the PDF as is.
Can anyone deny or confirm?
Regards, Michael
--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4347309.html
Sent from the iText - General mailing list archive at Nabble.com.
------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
iText-questions mailing list
https://lists.sourceforge.net/lists/listinfo/itext-questions
iText(R) is a registered trademark of 1T3XT BVBA.
Many questions posted to this list can (and will) be answered with a reference to the iText book: http://www.itextpdf.com/book/
Please check the keywords list before you ask for examples: http://itextpdf.com/themes/keywords.php
--
Andreas Kühne
phone: +49 177 293 24 97
mailto: ***@trustable.de

Trustable Ltd. Niederlassung Deutschland Ströverstr. 18 - 59427 Unna Amtsgericht Hamm HRB 5868

Directors Andreas Kühne, Heiko Veit

Company UK Company No: 5218868 Registered in England and Wales
mkl
2012-02-03 00:45:45 UTC
Permalink
Max, Andreas,
Post by Andreas Kuehne
Did you try to verify the signature within the signing code? If it
verifies, you're sure to have the right certificate selected.
I agree, Max should analyse the data he receives from the web page, the data
he currently without verification assumes to be the appropriately signed
correctly padded hash.

Regards, Michael

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4353328.html
Sent from the iText - General mailing list archive at Nabble.com.
madmax
2012-02-03 05:10:09 UTC
Permalink
Hi Michael and Andreas,



I have been trying to figure out what the issue could be based on your
comments.
1) In the JSP I did the following


The alert pops up the cert that was selected then I went into the details
tab and looked at the key usage it shows Digital Signature, Non-Repudiation
(c0) - see screen shot attached

2) Once the digest is signed and I send it back to the servlet I verify it
with some java code
And on the console it shows the following:



3) How can I verify if I have the right padding I am way in over my head at
this point
I have attached the Java method I used to verify (cannot take credit I
lifted it from
http://bozhobg.wordpress.com/2009/07/02/how-to-obtain-signers-details-from-a-javascript-signed-data/

I am beginning to wonder if my approach completely wrong in trying to get
itext to give me a digest then return it to the browser which then sings it
with the smart card and returns it back to the server where I inject it
back in the PDF?

When I Googled I could not really everget a definitive answer that this
implementation would actually work. Maybe it’s just not meant to work?


The smartcard is working I just tried to sign a PDF with my smart card
using Adobe professional and the document was signed correctly so it
something on my side butI doubt it’s itext.


Thanks again,

max

http://itext-general.2136553.n4.nabble.com/file/n4353694/verifyDigestt.java
verifyDigestt.java


Loading Image...
2-2-2012_23-59-17.png

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4353694.html
Sent from the iText - General mailing list archive at Nabble.com.
mkl
2012-02-03 09:18:29 UTC
Permalink
Max,
Post by madmax
Once the digest is signed and I send it back to the servlet I verify it
Your verifying Java code:
While I'm not too proficient in BouncyCastle usage, the JavaDocs tell me
that CMSSignedData is a "general class for handling a pkcs7-signature
message", and its constructor CMSSignedData(byte[] sigBlock) parses the byte
array parameter as a ContentInfo structure.

The fact that you can parse your "digest" with this class and retrieve
sensible information, therefore, strongly supports the former wild guess
that it not merely is an encrypted digest but instead already a full-fledged
PKCS#7 / CMS signature container.

Thus, you do not need to (actually you must not) embed it in a signature
container using the PdfPKCS7 utility class but instead embed it into the PDF
directly!
Post by madmax
I am beginning to wonder if this approach is completely wrong in trying
to get itext to give me a digest then return it to the browser which then
sings it with the smart card (CAPICOM activex) and returns it back to the
server where I inject it back in the PDF?
IMO it indeed appears to hold promise. Obviously, though, you should try
and make sure that the right certificate for the signature is selected (cf.
Andreas' recent comment), and of course you have to make sure that your
servlet<->jsp data connection cannot be hijacked by some attacker.
Post by madmax
But what is the alternative? (applet, activex, HSM)
That would depend on the details of the requirements of your project.

Regards, Michael

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4354087.html
Sent from the iText - General mailing list archive at Nabble.com.
madmax
2012-02-08 04:19:40 UTC
Permalink
Hi Michael
Post by mkl
Thus, you do not need to (actually you must not) embed it in a signature
container using the PdfPKCS7 utility class but instead embed it into the PDF
directly!
So are you saying that this might already be a signature? if so how do you
tell itext to embed the signature directly without using PdfPKCS7 - I
understand it but I am confused on how to do it?

Thanks,
max


--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4367972.html
Sent from the iText - General mailing list archive at Nabble.com.
madmax
2012-02-08 05:48:26 UTC
Permalink
Hi Michael
I looked a little dipper to what you were saying and begun looking closer to
my “verify” method and it dawned on me that I had seen similar code from
an example of detached signature and using BouncyCastle (source:
http://itextpdf.sourceforge.net/howtosign.html#signextdiccms
http://itextpdf.sourceforge.net/howtosign.html#signextdiccms

I rewrote the code to inject the signature as follows:



I am almost there adobe is no longer crashing when I look at the signature,
but when I try to verify it says “the document has been altered or
corrupted since the signature was applied” see attached jpg.

Is this related to a datetime stamp issue between the servlet reserving the
space for the digest and the browser creating the signature a few second
apart? Do you know how I could fix resolve this

Thanks again,


max


Loading Image...
2-8-2012_00-36-22.png

Loading Image...
2-8-2012_00-35-18.png

Loading Image...
2-8-2012_00-34-28.png

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4368253.html
Sent from the iText - General mailing list archive at Nabble.com.
mkl
2012-02-08 08:20:43 UTC
Permalink
Max,
Post by madmax
So are you saying that this might already be a signature?
Yes, it might be. As you unfortunately seem a bit reluctant to send samples,
I cannot tell for sure.
Post by madmax
if so how do you tell itext to embed the signature directly without using
PdfPKCS7
You used to do
As a first step simply reduce this to
In the resulting PDF you can now check whether the signature and the
signature container were created correctly. If they are not and you have
further questions, please do not refrain from supplying a sample generated
PDF. It would be great if you also supplied the hash your javascript
received for signing.

Regards, Michael

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4368743.html
Sent from the iText - General mailing list archive at Nabble.com.
mkl
2012-02-08 08:26:19 UTC
Permalink
Hhmmm, in the version of this posting I received via e-mail, the actual code
lines are missing. Maybe it's a bad idea to use nabble's raw tags...
therefore here without raw-tags...
Post by mkl
You used to do
byte[] data = Base64.decodeBase64(digest.trim().getBytes());
[...]
PdfPKCS7 sig = new PdfPKCS7(null, certChain, null, "SHA-256",
null, false);
[...]
byte[] ssig = sig.getEncodedPKCS7(null, cal, null, ocsp);
As a first step simply reduce this to
byte[] ssig = Base64.decodeBase64(digest.trim().getBytes());
Regards, Michael


--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4368759.html
Sent from the iText - General mailing list archive at Nabble.com.
madmax
2012-02-08 13:03:25 UTC
Permalink
Hi Michael, Andreas

As always thank you for your input.

I am attaching the updated sample code with the Java class and JSP. As well
as the original PDF and signed version of the document with my PIV card.

In the signPdf method the sample Java code has reduced the code to:
byte[] data= Base64.decodeBase64(digest.trim().getBytes());

I will continue to try different things on my side but if you know of how to
solve the date issue please let me know.

Best regards,

Max

http://itext-general.2136553.n4.nabble.com/file/n4369352/signed-sample-1.pdf
signed-sample-1.pdf
http://itext-general.2136553.n4.nabble.com/file/n4369352/original-sample-1.pdf
original-sample-1.pdf
Loading Image...
madmax-sig.jpg
http://itext-general.2136553.n4.nabble.com/file/n4369352/X509ServletExternalSignature.java
X509ServletExternalSignature.java
http://itext-general.2136553.n4.nabble.com/file/n4369352/x509ExternalSig.jsp
x509ExternalSig.jsp

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4369352.html
Sent from the iText - General mailing list archive at Nabble.com.
mkl
2012-02-08 14:42:22 UTC
Permalink
Max,
Post by madmax
byte[] data= Base64.decodeBase64(digest.trim().getBytes());
The data you received like that and then inserted in the PDF definitively is
a signature container.
Post by madmax
signed version of the document with my PIV card.
Unfortunately the container is not built as required in your PDF.

The signature dictionary in the PDF specifies that its /SubFilter is
/adbe.pkcs7.detached. According to the PDF spec (ISO 32000-1:2008 section
12.8.3.3.1) this has implications: In contrast to /adbe.pkcs7.sha1
signatures (for which the SHA1 digest of the document’s byte range shall be
encapsulated in the PKCS#7
SignedData field) no data shall be encapsulated in the PKCS#7 SignedData
field for /adbe.pkcs7.detached signatures.

Your signature, though, does have encapsulated data there:

encapContentInfo (EncapsulatedContentInfo) ::= SEQUENCE {
eContentType (Oid (Data)) 1.2.840.113549.1.7.1
eContent b900f400f100cc007b003f003f00bb00c600f200ea003700
}

This might be due to the fact that you call the CAPICOM.SignedData method
Sign with a bDetached parameter value "false".

Another problem becomes appearant here, though: Every other byte in your
encapsulated content is 00 which is not really likely to happen for hashes.
Thus, you seem to have to differently prepare your data.

As mentioned before, I do not use CAPICOM myself. Thus, I cannot tell you
how correctly to create a signature with it as required.
Post by madmax
I will continue to try different things on my side but if you know of how
to solve the date issue please let me know.
If you do not want to have a SigningTime signed attribute in your signature
container, simply don't add it in sign_IE().

Regards, Michael

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4369640.html
Sent from the iText - General mailing list archive at Nabble.com.
Andreas Kuehne
2012-02-08 21:36:58 UTC
Permalink
Hi Michael,

thanks for your detailed analysis of this signature. I was lost as our
verifier prodly states 'valid signature' while the reader marks
unspecified problems.

I'll go and add an additional check!

@Max: Looks like there is light at the end of the tunnel! Most problems
solved ...

Greetings

Andreas
Post by mkl
Max,
Post by madmax
byte[] data= Base64.decodeBase64(digest.trim().getBytes());
The data you received like that and then inserted in the PDF definitively is
a signature container.
Post by madmax
signed version of the document with my PIV card.
Unfortunately the container is not built as required in your PDF.
The signature dictionary in the PDF specifies that its /SubFilter is
/adbe.pkcs7.detached. According to the PDF spec (ISO 32000-1:2008 section
12.8.3.3.1) this has implications: In contrast to /adbe.pkcs7.sha1
signatures (for which the SHA1 digest of the document’s byte range shall be
encapsulated in the PKCS#7
SignedData field) no data shall be encapsulated in the PKCS#7 SignedData
field for /adbe.pkcs7.detached signatures.
encapContentInfo (EncapsulatedContentInfo) ::= SEQUENCE {
eContentType (Oid (Data)) 1.2.840.113549.1.7.1
eContent b900f400f100cc007b003f003f00bb00c600f200ea003700
}
This might be due to the fact that you call the CAPICOM.SignedData method
Sign with a bDetached parameter value "false".
Another problem becomes appearant here, though: Every other byte in your
encapsulated content is 00 which is not really likely to happen for hashes.
Thus, you seem to have to differently prepare your data.
As mentioned before, I do not use CAPICOM myself. Thus, I cannot tell you
how correctly to create a signature with it as required.
Post by madmax
I will continue to try different things on my side but if you know of how
to solve the date issue please let me know.
If you do not want to have a SigningTime signed attribute in your signature
container, simply don't add it in sign_IE().
Regards, Michael
--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4369640.html
Sent from the iText - General mailing list archive at Nabble.com.
------------------------------------------------------------------------------
Keep Your Developer Skills Current with LearnDevNow!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-d2d
_______________________________________________
iText-questions mailing list
https://lists.sourceforge.net/lists/listinfo/itext-questions
iText(R) is a registered trademark of 1T3XT BVBA.
Many questions posted to this list can (and will) be answered with a reference to the iText book: http://www.itextpdf.com/book/
Please check the keywords list before you ask for examples: http://itextpdf.com/themes/keywords.php
--
Andreas Kühne
phone: +49 177 293 24 97
mailto: ***@trustable.de

Trustable Ltd. Niederlassung Deutschland Ströverstr. 18 - 59427 Unna Amtsgericht Hamm HRB 5868

Directors Andreas Kühne, Heiko Veit

Company UK Company No: 5218868 Registered in England and Wales
madmax
2012-02-09 06:02:02 UTC
Permalink
Hi Michael and Andreas,

I tried several things:

1) removed the date stamps from both the itext and CAPICOM

2) Also changed the bDetached parameter value to "false" as suggested by
Michael in the javascript

3) I also noticed that I could avoid getting the digest from the PDF and
just created a signature using the browser and some dummy data that I could
pass. Then I can send it to the server and injecting into the PDF. For
example:


In all cases the signature was created but when it came to validating the
usual message "Document has been altered or corrupted since it was signed"

BTW, what tools do you guys use to debug the PDF generation with itext? just
the regular Eclipse debugger?

I think I am out of ideas for now, it's so close but I am just stumped at
the moment pretty furstrated. If you guys can think of anything else let me
know.

Thanks again I would not have gotten this far if it was not for your
suggestions.

max



--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4371978.html
Sent from the iText - General mailing list archive at Nabble.com.
a***@szomor.hu
2012-02-09 08:05:57 UTC
Permalink
using System;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using iTextSharp.text.pdf;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Security;

namespace PdfSignerTest
{
class Program
{
static void Main(string[] args)
{
try
{
Console.WriteLine("Start");

string inputFileName = @"..\..\..\Report.pdf";
string outputFileName = @"..\..\..\Signed.pdf";
string timeStampUrl = "http://www.xxxx.com/timestamp.cgi";

using (FileStream inputPdfStream = new
FileStream(inputFileName, FileMode.Open, FileAccess.Read))
{
using (FileStream outputPdfStream = new
FileStream(outputFileName, FileMode.Create, FileAccess.Write))
{
X509Certificate2 card = SelectCertificate();

SignPdf(card, inputPdfStream,
outputPdfStream, false, "Test Reason", "Test Location", "Test
Contact", timeStampUrl, "teszt", "teszt");
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
finally
{
Console.WriteLine("Done.");
Console.ReadLine();
}
}

/// <summary>
///
/// </summary>
/// <param name="certificate">smart card certificate</param>
/// <param name="inputPdfStream">input PDF</param>
/// <param name="outputPdfStream">output PDF (signed)</param>
/// <param name="append">append if <CODE>true</CODE> the
signature and all the other content will be added as a new revision
thus not invalidating existing signature</param>
/// <param name="reason">Reason field of signature</param>
/// <param name="location">Location field of signature</param>
/// <param name="contact">Contact field of signature</param>
/// <param name="tsaClientUrl">Timestamp server URL</param>
/// <param name="tsaClientLogin">Login user for timestamp
server (BASIC authentication)</param>
/// <param name="tsaClientPwd">Login password for timestamp
server</param>
public static void SignPdf(X509Certificate2 certificate,
Stream inputPdfStream, Stream outputPdfStream, bool append, string
reason, string location, string contact, string tsaClientUrl, string
tsaClientLogin, string tsaClientPwd)
{
// Building certificate chain for the OCSP verification
X509Chain ch = new X509Chain();
ch.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
ch.Build(certificate);

Org.BouncyCastle.X509.X509Certificate[] chain = new
Org.BouncyCastle.X509.X509Certificate[ch.ChainElements.Count];
Org.BouncyCastle.X509.X509CertificateParser cp = new
Org.BouncyCastle.X509.X509CertificateParser();
int i = 0;

foreach (X509ChainElement element in ch.ChainElements)
{
Org.BouncyCastle.X509.X509Certificate chainElement =
cp.ReadCertificate(element.Certificate.RawData);
chain[i] = chainElement;
i++;
}

//Org.BouncyCastle.X509.X509CertificateParser cp = new
Org.BouncyCastle.X509.X509CertificateParser();
//Org.BouncyCastle.X509.X509Certificate[] chain = new
Org.BouncyCastle.X509.X509Certificate[] {
cp.ReadCertificate(certificate.RawData) };

PdfReader reader = new PdfReader(inputPdfStream);
PdfStamper st = PdfStamper.CreateSignature(reader,
outputPdfStream, '\0', null, append);
PdfSignatureAppearance sap = st.SignatureAppearance;

sap.SetCrypto(null, chain, null,
PdfSignatureAppearance.SELF_SIGNED);

sap.Reason = reason;
sap.Contact = contact;
sap.Location = location;

sap.SetVisibleSignature(new iTextSharp.text.Rectangle(50,
50, 200, 100), 1, null);

PdfSignature dic = new
PdfSignature(PdfName.ADOBE_PPKLITE, new PdfName("adbe.pkcs7.detached"));
dic.Reason = sap.Reason;
dic.Location = sap.Location;
dic.Contact = sap.Contact;
dic.Date = new PdfDate(sap.SignDate);
sap.CryptoDictionary = dic;

int contentEstimated = 15000;

Dictionary<PdfName, int> exc = new Dictionary<PdfName, int>();
exc[PdfName.CONTENTS] = contentEstimated * 2 + 2;
sap.PreClose(exc);

PdfPKCS7 sgn = new PdfPKCS7(null, chain, null, "SHA1", false);
IDigest messageDigest = DigestUtilities.GetDigest("SHA1");
Stream data = sap.RangeStream;
byte[] buf = new byte[8192];
int n;
while ((n = data.Read(buf, 0, buf.Length)) > 0)
{
messageDigest.BlockUpdate(buf, 0, n);
}
byte[] hash = new byte[messageDigest.GetDigestSize()];
messageDigest.DoFinal(hash, 0);
DateTime cal = DateTime.Now;
byte[] ocsp = null;
if (chain.Length >= 2)
{
String url = PdfPKCS7.GetOCSPURL(chain[0]);
if (url != null && url.Length > 0)
ocsp = new OcspClientBouncyCastle(chain[0],
chain[1], url).GetEncoded();

//File.WriteAllBytes(@"..\..\..\ocsp.pdf", ocsp);
}
byte[] sh = sgn.GetAuthenticatedAttributeBytes(hash, cal, ocsp);

// SHA1withRSA calculated by CAPI
byte[] signedHashValue = SignSHA1withRSA(certificate, sh);
sgn.SetExternalDigest(signedHashValue, hash, "RSA");

byte[] paddedSig = new byte[contentEstimated];

if (!string.IsNullOrEmpty(tsaClientUrl))
{
TSAClientBouncyCastle tsc = new
TSAClientBouncyCastle(tsaClientUrl, tsaClientLogin, tsaClientPwd);
byte[] encodedSigTsa = sgn.GetEncodedPKCS7(hash, cal,
tsc, ocsp);
System.Array.Copy(encodedSigTsa, 0, paddedSig, 0,
encodedSigTsa.Length);
if (contentEstimated + 2 < encodedSigTsa.Length)
throw new ApplicationException("Not enough space
for signature");
}
else
{
byte[] encodedSig = sgn.GetEncodedPKCS7(hash, cal,
null, ocsp);
System.Array.Copy(encodedSig, 0, paddedSig, 0,
encodedSig.Length);
if (contentEstimated + 2 < encodedSig.Length)
throw new ApplicationException("Not enough space
for signature");
}

PdfDictionary dic2 = new PdfDictionary();
dic2.Put(PdfName.CONTENTS, new
PdfString(paddedSig).SetHexWriting(true));
sap.Close(dic2);
}

public static byte[] SignSHA1withRSA(X509Certificate2
certificate, byte[] input)
{
const Int32 CRYPT_ACQUIRE_USE_PROV_INFO_FLAG = 0x00000002;
const Int32 CRYPT_ACQUIRE_COMPARE_KEY_FLAG = 0x00000004;

IntPtr privateKeyHandle = IntPtr.Zero;
bool isCallerNeedFreeKeyHandle = false;
IntPtr hashHandle = IntPtr.Zero;
byte[] result = null;

try
{
IntPtr cardHandle = certificate.Handle;
Int32 pdwKeySpec = Crypto.AT_SIGNATURE;

if
(!Crypto.CryptAcquireCertificatePrivateKey(cardHandle,
CRYPT_ACQUIRE_USE_PROV_INFO_FLAG |

CRYPT_ACQUIRE_COMPARE_KEY_FLAG, IntPtr.Zero, ref privateKeyHandle, ref
pdwKeySpec, ref isCallerNeedFreeKeyHandle))
{
throw new
CryptographicException(Marshal.GetLastWin32Error());
}

if (!Crypto.CryptCreateHash(privateKeyHandle,
Crypto.CALG_SHA1, IntPtr.Zero, 0, ref hashHandle))
{
throw new
CryptographicException(Marshal.GetLastWin32Error());
}

MemoryStream streamInput = new MemoryStream(input);
byte[] buffer = new byte[4096];

while (true)
{
int read = streamInput.Read(buffer, 0, buffer.Length);

if (read == 0)
break;

if (!Crypto.CryptHashData(hashHandle, buffer, read, 0))
{
throw new
CryptographicException(Marshal.GetLastWin32Error());
}
}

int pwdSigLen = 0;
if (!Crypto.CryptSignHash(hashHandle, pdwKeySpec,
null, 0, null, ref pwdSigLen))
{
throw new
CryptographicException(Marshal.GetLastWin32Error());
}

result = new byte[pwdSigLen];

if (!Crypto.CryptSignHash(hashHandle, pdwKeySpec,
null, 0, result, ref pwdSigLen))
{
throw new
CryptographicException(Marshal.GetLastWin32Error());
}

// CAPI generated hash has a different indian order
Array.Reverse(result);
}
finally
{

if (hashHandle != IntPtr.Zero)
{
if (!Crypto.CryptDestroyHash(hashHandle))
{
throw new
CryptographicException(Marshal.GetLastWin32Error());
}
}

if (isCallerNeedFreeKeyHandle && privateKeyHandle !=
IntPtr.Zero)
{
if (!Crypto.CryptReleaseContext(privateKeyHandle, 0))
{
throw new
CryptographicException(Marshal.GetLastWin32Error());
}
}
}

return result;

}

public static X509Certificate2 SelectCertificate()
{
X509Store st = new X509Store(StoreName.My,
StoreLocation.CurrentUser);
st.Open(OpenFlags.ReadOnly);
X509Certificate2Collection col =
st.Certificates.Find(X509FindType.FindByKeyUsage,
X509KeyUsageFlags.NonRepudiation, true);

X509Certificate2 card = null;
X509Certificate2Collection sel =
X509Certificate2UI.SelectFromCollection(col, "Certificates", "Select
one to sign", X509SelectionFlag.SingleSelection);
if (sel.Count > 0)
{
X509Certificate2Enumerator en = sel.GetEnumerator();
en.MoveNext();
card = en.Current;
}
st.Close();
return card;
}
}
}


This is a working code, but unfortunatly copied from a Hungarian blog:
http://gubus2.wordpress.com/2010/09/01/elektronikus-alairas-keszitese-pdf-allomanyra-smart-card-tamogatassal-net-alatt/
Raffaele
2012-02-09 12:08:31 UTC
Permalink
Hi aszomor,

i've tried your sample code, but Adobe say that the PDF file is Modified.

If i call the GetEncodedPKCS7 method without the "secondDigest" parameter,
it's all ok but into the signature tjere aren't the signed attributes.

Any suggestion???


Thanks

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4372614.html
Sent from the iText - General mailing list archive at Nabble.com.
a***@szomor.hu
2012-02-09 14:26:52 UTC
Permalink
sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED;
beore sgn.SetExternalDigest
Post by Raffaele
Hi aszomor,
i've tried your sample code, but Adobe say that the PDF file is Modified.
If i call the GetEncodedPKCS7 method without the "secondDigest" parameter,
it's all ok but into the signature tjere aren't the signed attributes.
Any suggestion???
Thanks
--
http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4372614.html
Sent from the iText - General mailing list archive at Nabble.com.
------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning
Cloud computing makes use of virtualization - but cloud computing
also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
iText-questions mailing list
https://lists.sourceforge.net/lists/listinfo/itext-questions
iText(R) is a registered trademark of 1T3XT BVBA.
Many questions posted to this list can (and will) be answered with a
reference to the iText book: http://www.itextpdf.com/book/
http://itextpdf.com/themes/keywords.php
Raffaele
2012-02-09 14:54:41 UTC
Permalink
Hi aszomor,

same result!!!

Are 2 days that i'm facing with this issue:

If i would to include the "signed attributes" into the PKCS#7 envelope,
Adobe say that the PDF as changed.
Otherwise if i decide do not include "signed attributes", it' all ok.

I've posted the question in other thread on this same mailing list, but
nobody has gived to me an answer.


Any suggestion???

Thanks.

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4373113.html
Sent from the iText - General mailing list archive at Nabble.com.
a***@szomor.hu
2012-02-09 15:58:23 UTC
Permalink
see the book examples at part3 and chapter12

/*
* This class is part of the book "iText in Action - 2nd Edition"
* written by Bruno Lowagie (ISBN: 9781935182610)
* For more info, go to: http://itextpdf.com/examples/
* This example only works with the AGPL version of iText.
*/
package part3.chapter12;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Properties;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfPKCS7;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;

public class Signatures {

/** The resulting PDF */
public static String ORIGINAL = "results/part3/chapter12/hello.pdf";
/** The resulting PDF */
public static String SIGNED1 = "results/part3/chapter12/signature_1.pdf";
/** The resulting PDF */
public static String SIGNED2 = "results/part3/chapter12/signature_2.pdf";
/** Info after verification of a signed PDF */
public static String VERIFICATION = "results/part3/chapter12/verify.txt";
/** The resulting PDF */
public static String REVISION = "results/part3/chapter12/revision_1.pdf";

/**
* A properties file that is PRIVATE.
* You should make your own properties file and adapt this line.
*/
public static String PATH = "c:/home/blowagie/key.properties";
/** Some properties used when signing. */
public static Properties properties = new Properties();
/** One of the resources. */
public static final String RESOURCE = "resources/img/logo.gif";

/**
* Creates a PDF document.
* @param filename the path to the new PDF document
* @throws DocumentException
* @throws IOException
*/
public void createPdf(String filename) throws IOException,
DocumentException {
Document document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(filename));
document.open();
document.add(new Paragraph("Hello World!"));
document.close();
}

/**
* Manipulates a PDF file src with the file dest as result
* @param src the original PDF
* @param dest the resulting PDF
* @throws IOException
* @throws DocumentException
* @throws GeneralSecurityException
*/
public void signPdfFirstTime(String src, String dest)
throws IOException, DocumentException, GeneralSecurityException {
String path = properties.getProperty("PRIVATE");
String keystore_password = properties.getProperty("PASSWORD");
String key_password = properties.getProperty("PASSWORD");
KeyStore ks = KeyStore.getInstance("pkcs12", "BC");
ks.load(new FileInputStream(path), keystore_password.toCharArray());
String alias = (String)ks.aliases().nextElement();
PrivateKey key = (PrivateKey) ks.getKey(alias,
key_password.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper
.getSignatureAppearance();
appearance.setCrypto(key, chain, null,
PdfSignatureAppearance.WINCER_SIGNED);
appearance.setImage(Image.getInstance(RESOURCE));
appearance.setReason("I've written this.");
appearance.setLocation("Foobar");
appearance.setVisibleSignature(new Rectangle(72, 732, 144,
780), 1, "first");
stamper.close();
}

/**
* Manipulates a PDF file src with the file dest as result
* @param src the original PDF
* @param dest the resulting PDF
* @throws IOException
* @throws DocumentException
* @throws GeneralSecurityException
*/
public void signPdfSecondTime(String src, String dest)
throws IOException, DocumentException, GeneralSecurityException {
String path = "resources/encryption/.keystore";
String keystore_password = "f00b4r";
String key_password = "f1lmf3st";
String alias = "foobar";
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(new FileInputStream(path), keystore_password.toCharArray());
PrivateKey key = (PrivateKey) ks.getKey(alias,
key_password.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os,
'\0', null, true);
PdfSignatureAppearance appearance = stamper
.getSignatureAppearance();
appearance.setCrypto(key, chain, null,
PdfSignatureAppearance.WINCER_SIGNED);
appearance.setReason("I'm approving this.");
appearance.setLocation("Foobar");
appearance.setVisibleSignature(new Rectangle(160, 732, 232,
780), 1, "second");
stamper.close();

}

/**
* Verifies the signatures of a PDF we've signed twice.
* @throws GeneralSecurityException
* @throws IOException
*/
public void verifySignatures() throws GeneralSecurityException,
IOException {
KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
ks.load(null, null);
CertificateFactory cf = CertificateFactory.getInstance("X509");
FileInputStream is1 = new
FileInputStream(properties.getProperty("ROOTCERT"));
X509Certificate cert1 = (X509Certificate) cf.generateCertificate(is1);
ks.setCertificateEntry("cacert", cert1);
FileInputStream is2 = new
FileInputStream("resources/encryption/foobar.cer");
X509Certificate cert2 = (X509Certificate) cf.generateCertificate(is2);
ks.setCertificateEntry("foobar", cert2);

PrintWriter out = new PrintWriter(new FileOutputStream(VERIFICATION));
PdfReader reader = new PdfReader(SIGNED2);
AcroFields af = reader.getAcroFields();
ArrayList<String> names = af.getSignatureNames();
for (String name : names) {
out.println("Signature name: " + name);
out.println("Signature covers whole document: " +
af.signatureCoversWholeDocument(name));
out.println("Document revision: " + af.getRevision(name)
+ " of " + af.getTotalRevisions());
PdfPKCS7 pk = af.verifySignature(name);
Calendar cal = pk.getSignDate();
Certificate[] pkc = pk.getCertificates();
out.println("Subject: " +
PdfPKCS7.getSubjectFields(pk.getSigningCertificate()));
out.println("Revision modified: " + !pk.verify());
Object fails[] = PdfPKCS7.verifyCertificates(pkc, ks, null, cal);
if (fails == null)
out.println("Certificates verified against the KeyStore");
else
out.println("Certificate failed: " + fails[1]);
}
out.flush();
out.close();
}

/**
* Extracts the first revision of a PDF we've signed twice.
* @throws IOException
*/
public void extractFirstRevision() throws IOException {
PdfReader reader = new PdfReader(SIGNED2);
AcroFields af = reader.getAcroFields();
FileOutputStream os = new FileOutputStream(REVISION);
byte bb[] = new byte[1028];
InputStream ip = af.extractRevision("first");
int n = 0;
while ((n = ip.read(bb)) > 0)
os.write(bb, 0, n);
os.close();
ip.close();
}

/**
* Main method.
*
* @param args no arguments needed
* @throws DocumentException
* @throws IOException
* @throws GeneralSecurityException
*/
public static void main(String[] args)
throws IOException, DocumentException, GeneralSecurityException {
Security.addProvider(new BouncyCastleProvider());
properties.load(new FileInputStream(PATH));
Signatures signatures = new Signatures();
signatures.createPdf(ORIGINAL);
signatures.signPdfFirstTime(ORIGINAL, SIGNED1);
signatures.signPdfSecondTime(SIGNED1, SIGNED2);
signatures.verifySignatures();
signatures.extractFirstRevision();
}
}

--------------------------------------------------------

/*
* This class is part of the book "iText in Action - 2nd Edition"
* written by Bruno Lowagie (ISBN: 9781935182610)
* For more info, go to: http://itextpdf.com/examples/
* This example only works with the AGPL version of iText.
*/
package part3.chapter12;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.Security;
import java.security.Signature;
import java.security.cert.Certificate;
import java.util.Properties;

import org.bouncycastle.jce.provider.BouncyCastleProvider;

import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfDictionary;
import com.itextpdf.text.pdf.PdfLiteral;
import com.itextpdf.text.pdf.PdfName;
import com.itextpdf.text.pdf.PdfPKCS7;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSigGenericPKCS;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfString;

public class SignatureExternalHash {

/**
* A properties file that is PRIVATE.
* You should make your own properties file and adapt this line.
*/
public static String PATH = "c:/home/blowagie/key.properties";
/** Some properties used when signing. */
public static Properties properties = new Properties();

/** The resulting PDF */
public static String SIGNED1 =
"results/part3/chapter12/externalhash_1.pdf";
/** The resulting PDF */
public static String SIGNED2 =
"results/part3/chapter12/externalhash_2.pdf";
/** The resulting PDF */
public static String SIGNED3 =
"results/part3/chapter12/externalhash_3.pdf";

/**
* Manipulates a PDF file src with the file dest as result
* @param src the original PDF
* @param dest the resulting PDF
* @throws IOException
* @throws DocumentException
* @throws GeneralSecurityException
*/
public void signPdfSelf(String src, String dest)
throws IOException, DocumentException, GeneralSecurityException {
// Private key and certificate
String path = properties.getProperty("PRIVATE");
String keystore_password = properties.getProperty("PASSWORD");
String key_password = properties.getProperty("PASSWORD");
KeyStore ks = KeyStore.getInstance("pkcs12", "BC");
ks.load(new FileInputStream(path), keystore_password.toCharArray());
String alias = (String)ks.aliases().nextElement();
PrivateKey key = (PrivateKey) ks.getKey(alias,
key_password.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
// reader and stamper
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setCrypto(null, chain, null,
PdfSignatureAppearance.SELF_SIGNED);
appearance.setReason("External hash example");
appearance.setLocation("Foobar");
appearance.setVisibleSignature(new Rectangle(72, 732, 144,
780), 1, "sig");
appearance.setExternalDigest(new byte[128], null, "RSA");
appearance.preClose();
// digital signature
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initSign(key);
byte buf[] = new byte[8192];
int n;
InputStream inp = appearance.getRangeStream();
while ((n = inp.read(buf)) > 0) {
signature.update(buf, 0, n);
}
PdfPKCS7 sig = appearance.getSigStandard().getSigner();
sig.setExternalDigest(signature.sign(), null, "RSA");
PdfDictionary dic = new PdfDictionary();
dic.put(PdfName.CONTENTS, new
PdfString(sig.getEncodedPKCS1()).setHexWriting(true));
appearance.close(dic);
}
/**
* Manipulates a PDF file src with the file dest as result
* @param src the original PDF
* @param dest the resulting PDF
* @throws IOException
* @throws DocumentException
* @throws GeneralSecurityException
*/
public void signPdfWinCer(String src, String dest, boolean sign)
throws IOException, DocumentException, GeneralSecurityException {
// private key and certificate
String path = properties.getProperty("PRIVATE");
String keystore_password = properties.getProperty("PASSWORD");
String key_password = properties.getProperty("PASSWORD");
KeyStore ks = KeyStore.getInstance("pkcs12", "BC");
ks.load(new FileInputStream(path), keystore_password.toCharArray());
String alias = (String)ks.aliases().nextElement();
PrivateKey key = (PrivateKey) ks.getKey(alias,
key_password.toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
// reader and stamper
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setCrypto(key, chain, null,
PdfSignatureAppearance.WINCER_SIGNED);
appearance.setReason("External hash example");
appearance.setLocation("Foobar");
appearance.setVisibleSignature(new Rectangle(72, 732, 144,
780), 1, "sig");
appearance.setExternalDigest(null, new byte[20], null);
appearance.preClose();
// signature
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
byte buf[] = new byte[8192];
int n;
InputStream inp = appearance.getRangeStream();
while ((n = inp.read(buf)) > 0) {
messageDigest.update(buf, 0, n);
}
byte hash[] = messageDigest.digest();
PdfSigGenericPKCS sg = appearance.getSigStandard();
PdfLiteral slit = (PdfLiteral)sg.get(PdfName.CONTENTS);
byte[] outc = new byte[(slit.getPosLength() - 2) / 2];
PdfPKCS7 sig = sg.getSigner();
if (sign) {
Signature signature = Signature.getInstance("SHA1withRSA");
signature.initSign(key);
signature.update(hash);
sig.setExternalDigest(signature.sign(), hash, "RSA");
}
else
sig.setExternalDigest(null, hash, null);
PdfDictionary dic = new PdfDictionary();
byte[] ssig = sig.getEncodedPKCS7();
System.arraycopy(ssig, 0, outc, 0, ssig.length);
dic.put(PdfName.CONTENTS, new PdfString(outc).setHexWriting(true));
appearance.close(dic);
}

/**
* Main method.
*
* @param args no arguments needed
* @throws DocumentException
* @throws IOException
* @throws GeneralSecurityException
*/
public static void main(String[] args)
throws IOException, DocumentException, GeneralSecurityException {
Security.addProvider(new BouncyCastleProvider());
properties.load(new FileInputStream(PATH));
new Signatures().createPdf(Signatures.ORIGINAL);
SignatureExternalHash signatures = new SignatureExternalHash();
signatures.signPdfSelf(Signatures.ORIGINAL, SIGNED1);
signatures.signPdfWinCer(Signatures.ORIGINAL, SIGNED2, false);
signatures.signPdfWinCer(Signatures.ORIGINAL, SIGNED3, true);
}
}
Raffaele
2012-02-09 16:22:19 UTC
Permalink
None of the examples as solved the problem!!!

I've seen these examples many and many times without success!!!!



Any suggestion???

Thanks

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4373383.html
Sent from the iText - General mailing list archive at Nabble.com.
Leonard Rosenthol
2012-02-10 12:42:20 UTC
Permalink
If Adobe Reader (Adobe is a company, Reader is one of our products) says the file is modified, that's DIFFERENT from what you are putting into the envelope.

Modified means that the hashes don't match. Check yoru hash computation.

-----Original Message-----
From: Raffaele [mailto:***@libero.it]
Sent: Thursday, February 09, 2012 9:55 AM
To: itext-***@lists.sourceforge.net
Subject: Re: [iText-questions] Sign and PDF with SmartCard and web browser only

Hi aszomor,

same result!!!

Are 2 days that i'm facing with this issue:

If i would to include the "signed attributes" into the PKCS#7 envelope, Adobe say that the PDF as changed.
Otherwise if i decide do not include "signed attributes", it' all ok.

I've posted the question in other thread on this same mailing list, but nobody has gived to me an answer.


Any suggestion???

Thanks.

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4373113.html
Sent from the iText - General mailing list archive at Nabble.com.

------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning Cloud computing makes use of virtualization - but cloud computing also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
iText-questions mailing list
iText-***@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/itext-questions

iText(R) is a registered trademark of 1T3XT BVBA.
Many questions posted to this list can (and will) be answered with a reference to the iText book: http://www.itextpdf.com/book/ Please check the keywords list before you ask for examples: http://itextpdf.com/themes/keywords.php
Raffaele
2012-02-10 13:04:50 UTC
Permalink
Thanks Leonard,

you observation is correct but i want you to notice that if i call the
method GetEncodedPKCS7 without any parameter Reader say that the file isn't
modified.

How do you explain this???

Thanks.

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4376179.html
Sent from the iText - General mailing list archive at Nabble.com.
Leonard Rosenthol
2012-02-10 14:23:59 UTC
Permalink
Don't know that API, so I can't explain how it works.

If you post actual PDF files that I can open up in Reader and trace through what our code is doing, then I can answer it.

Leonard

-----Original Message-----
From: Raffaele [mailto:***@libero.it]
Sent: Friday, February 10, 2012 8:05 AM
To: itext-***@lists.sourceforge.net
Subject: Re: [iText-questions] Sign and PDF with SmartCard and web browser only

Thanks Leonard,

you observation is correct but i want you to notice that if i call the method GetEncodedPKCS7 without any parameter Reader say that the file isn't modified.

How do you explain this???

Thanks.

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4376179.html
Sent from the iText - General mailing list archive at Nabble.com.

------------------------------------------------------------------------------
Virtualization & Cloud Management Using Capacity Planning Cloud computing makes use of virtualization - but cloud computing also focuses on allowing computing to be delivered as a service.
http://www.accelacomm.com/jaw/sfnl/114/51521223/
_______________________________________________
iText-questions mailing list
iText-***@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/itext-questions

iText(R) is a registered trademark of 1T3XT BVBA.
Many questions posted to this list can (and will) be answered with a reference to the iText book: http://www.itextpdf.com/book/ Please check the keywords list before you ask for examples: http://itextpdf.com/themes/keywords.php
arnabroy
2014-09-04 03:53:20 UTC
Permalink
hi michael/leonard
please help me out



--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4660329.html
Sent from the iText - General mailing list archive at Nabble.com.
iText mailing list
2014-09-04 05:49:21 UTC
Permalink
Post by arnabroy
hi michael/leonard
please help me out
This sounds very odd:
i am sending it back to the server side to embed it into the pdf file
using bouncy castle.

Did you take a look at this example:
http://sourceforge.net/p/itext/code/HEAD/tree/tutorial/signatures/src/main/java/signatures/chapter4/C4_09_DeferredSigning.java
arnabroy
2014-09-04 10:50:47 UTC
Permalink
i am actually signing the document hash in the client browser by using
capicom dll in javascript *and not by itextsharp*.

the actual document is in the server side. so, the signed hash is embedded
in the pdf file by using itextsharp in the server.

after embedding the CAPICOM generated signature in the pdf file through
itextsharp i am getting the following error:
"The Document has been altered or corrupted since the Signature was
applied."

please help.



--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4660335.html
Sent from the iText - General mailing list archive at Nabble.com.
mkl
2014-09-04 13:27:50 UTC
Permalink
arnabroy,
Post by arnabroy
i am actually signing the document hash in the client browser by using
capicom dll in javascript
*
Post by arnabroy
and not by itextsharp
*
Post by arnabroy
.
the actual document is in the server side. so, the signed hash is embedded
in the pdf file by using itextsharp in the server.
You claim you are /signing the document hash in the client browser/. That is
not true: The "hash" you send to the client is not the document hash but
instead:

Default.cs:

PdfPKCS7 sgn = new PdfPKCS7(null, chain, "SHA1", false);
...
byte[] sh = sgn.getAuthenticatedAttributeBytes(hash, cal.TodaysDate,
null, null, CryptoStandard.CMS);
...
hdnSignatureHash.Text = System.Text.Encoding.Unicode.GetString(sh);

Thus, you start by creating a CMS signature using iTextSharp helper classes
(PdfPKCS7), take the resulting authenticated attributes to be signed, and
try to send them to the client. I say 'try' because by interpreting them as
Unicode of some text (Unicode.GetString(sh)) you already utterly destroy
them.

But let's assume you sent them to the client in a viable manner...

Default.aspx:

var SignedData = new ActiveXObject("CAPICOM.SignedData");
SignedData.Content =
document.getElementById("FeaturedContent_hdnSignatureHash").value;
var Signer = new ActiveXObject("CAPICOM.Signer");
Signer.Certificate = cert;
var szSignature = SignedData.Sign(Signer, true, CAPICOM_ENCODE_BASE64);
SignedData.Verify(szSignature, true, CAPICOM_VERIFY_SIGNATURE_ONLY);
document.getElementById("FeaturedContent_hdnSignature").value =
szSignature;

On the client you now create a detached CMS signature of the afore-mentioned
authenticated attributes and send that signature container bas64-encoded
back to the server.

Default.cs:

Org.BouncyCastle.Cms.CmsSignedData cms = new
Org.BouncyCastle.Cms.CmsSignedData(Convert.FromBase64String(hdnSignature.Text));
byte[] encodedSig = cms.GetEncoded();

byte[] paddedSig = new byte[8192];
Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length);
PdfDictionary dic2 = new PdfDictionary();
dic2.Put(PdfName.CONTENTS, new
PdfString(paddedSig).SetHexWriting(true));
sap.Close(dic2);

On the server you use BouncyCastle essentially only to base64-decode the CMS
container created by the client and insert it as is into the PDF.

Thus, the data signed by the signature (the authenticated attributes
prepared by iTextSharp) are thrown away and the signature is injected into a
PDF which it hardly has anything to do with.


What you need to do first:

1. Choose what shall create the CMS SignerInfo structure, either iTextSharp
server-side, or CAPICOM client-side or BouncyCastle server-side. Adjust your
code to that choice.

2. Transfer data properly, especially don't interpret arbitrary bytes as
Unicode text but instead transfer them base64-encoded.

Furthermore the CMS container created by your way of using CAPICOM is very
minimal, it does not provide any of the authenticated attributes nowadays
required by many signature profiles but instead only signs the given data.

I don't know enough CAPICOM to tell whether it can create up-to-date
signatures. You may have to switch or do some funny de- and reassembling of
signature structures.

regards, Michael



--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4660336.html
Sent from the iText - General mailing list archive at Nabble.com.
arnabroy
2014-09-04 17:15:45 UTC
Permalink
hi michael,
same error file corrupted
please help

STEP1: creating the hash of the pdf file in the server
protected void Button1_Click(object sender, EventArgs e)
{
string _gstrFilePath =
Server.MapPath("~/NewFolder1/TRANSFER_[PROVISIONAL]_29_05_2014.pdf");
SHA1Managed sha1 = new SHA1Managed();
UnicodeEncoding encoding = new UnicodeEncoding();
byte[] data1 = File.ReadAllBytes(_gstrFilePath);
byte[] hash1 = sha1.ComputeHash(data1);
hdnSignatureHash.Text = Convert.ToBase64String(hash1);
}

STEP2: getting the certificate and signed hash in the client side
javascript:
function fnGetCertificate() {
var obj = new ActiveXObject('PDFSIGNATURE.PDFSIG');
var cer = obj.PdfSignature("1A87CCE901002C24");
document.getElementById("FeaturedContent_hdnCertificate").value
= cer;
}
function fnGetSignature() {
var obj = new ActiveXObject('PDFSIGNATURE.PDFSIG');
var signedhash = obj.PdfSignedHash("1A87CCE901002C24",
document.getElementById("FeaturedContent_hdnSignatureHash").value);
document.getElementById("FeaturedContent_hdnSignature").value =
signedhash;
}

.net dll in the client side
public string PdfSignature(string SerialNumber)
{
bool Success = false;
byte[] extCert = null;
String strReturn = string.Empty;
try
{

System.Security.Cryptography.X509Certificates.X509Store
store = new System.Security.Cryptography.X509Certificates.X509Store("MY",
System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser);

store.Open(System.Security.Cryptography.X509Certificates.OpenFlags.ReadOnly
| System.Security.Cryptography.X509Certificates.OpenFlags.OpenExistingOnly);

//System.Security.Cryptography.X509Certificates.X509Certificate2Collection
sel =
System.Security.Cryptography.X509Certificates.X509Certificate2UI.SelectFromCollection(store.Certificates,
null, null,
System.Security.Cryptography.X509Certificates.X509SelectionFlag.SingleSelection);


System.Security.Cryptography.X509Certificates.X509Certificate2 cert =
store.Certificates.Find(System.Security.Cryptography.X509Certificates.X509FindType.FindBySerialNumber,
SerialNumber, false)[0];

//System.Security.Cryptography.X509Certificates.X509Certificate2 cert =
store.Certificates[0];
Org.BouncyCastle.X509.X509CertificateParser cp = new
Org.BouncyCastle.X509.X509CertificateParser();
Org.BouncyCastle.X509.X509Certificate[] chain = new
Org.BouncyCastle.X509.X509Certificate[] {
cp.ReadCertificate(cert.RawData)};
return
Convert.ToBase64String(cert.Export(System.Security.Cryptography.X509Certificates.X509ContentType.Cert,
"PASSWORD"));

}
catch (Exception ex)
{
strReturn = ex.Message;
return strReturn;
}
}

[ComVisible(true)]
public string PdfSignedHash(string SerialNumber,string hash)
{
bool Success = false;
byte[] signedhash = null;
String strReturn = string.Empty;
try
{

System.Security.Cryptography.X509Certificates.X509Store
store = new System.Security.Cryptography.X509Certificates.X509Store("MY",
System.Security.Cryptography.X509Certificates.StoreLocation.CurrentUser);

store.Open(System.Security.Cryptography.X509Certificates.OpenFlags.ReadOnly
| System.Security.Cryptography.X509Certificates.OpenFlags.OpenExistingOnly);

//System.Security.Cryptography.X509Certificates.X509Certificate2Collection
sel =
System.Security.Cryptography.X509Certificates.X509Certificate2UI.SelectFromCollection(store.Certificates,
null, null,
System.Security.Cryptography.X509Certificates.X509SelectionFlag.SingleSelection);


System.Security.Cryptography.X509Certificates.X509Certificate2 ocert =
store.Certificates.Find(System.Security.Cryptography.X509Certificates.X509FindType.FindBySerialNumber,
SerialNumber, false)[0];
System.Security.Cryptography.RSACryptoServiceProvider
privateKey =
(System.Security.Cryptography.RSACryptoServiceProvider)ocert.PrivateKey;
signedhash =
privateKey.SignHash(Convert.FromBase64String(hash), "SHA1");


return Convert.ToBase64String(signedhash);

}
catch (Exception ex)
{
strReturn = ex.Message;
return strReturn;
}
}

STEP 3: sign pdf by itextsharp in the server
protected void Button2_Click(object sender, EventArgs e)
{
string _gstrFilePath =
Server.MapPath("~/NewFolder1/TRANSFER_[PROVISIONAL]_29_05_2014.pdf");
System.Security.Cryptography.X509Certificates.X509Certificate2
oCert = new
System.Security.Cryptography.X509Certificates.X509Certificate2(Convert.FromBase64String(hdnCertificate.Text),
"PASSWORD");

Org.BouncyCastle.X509.X509CertificateParser cp = new
Org.BouncyCastle.X509.X509CertificateParser();
Org.BouncyCastle.X509.X509Certificate[] chain = new
Org.BouncyCastle.X509.X509Certificate[] {
cp.ReadCertificate(oCert.RawData)};

/*start verification*/
RSACryptoServiceProvider csp =
(RSACryptoServiceProvider)oCert.PublicKey.Key;

// Hash the data
SHA1Managed sha1 = new SHA1Managed();
UnicodeEncoding encoding = new UnicodeEncoding();
byte[] data1 = File.ReadAllBytes(_gstrFilePath);
byte[] hash1 = sha1.ComputeHash(data1);
bool bln = csp.VerifyHash(hash1,
CryptoConfig.MapNameToOID("SHA1"),
Convert.FromBase64String(hdnSignature.Text));
/*end verification*/

ServerSignature externalSignature = new ServerSignature();
externalSignature.DigSign =
Convert.FromBase64String(hdnSignature.Text);

// reader and stamper
byte[] OwnerPassword =
System.Text.Encoding.ASCII.GetBytes("secret");

PdfReader reader = new PdfReader(_gstrFilePath, OwnerPassword);
bool isencrypted = reader.IsEncrypted();
bool hasuserPassword = false;

string OutputFilename =
Server.MapPath("~/NewFolder1/TRANSFER_[PROVISIONAL]_29_05_20141.pdf");
using (FileStream fout = new FileStream(OutputFilename,
FileMode.Create, FileAccess.ReadWrite))
{
using (PdfStamper stamper =
PdfStamper.CreateSignature(reader, fout, '\0'))
{
if (isencrypted)
stamper.SetEncryption(PdfWriter.STRENGTH128BITS,
null, "secret", PdfWriter.ALLOW_SCREENREADERS);
if (hasuserPassword)
stamper.SetEncryption(PdfWriter.STRENGTH128BITS,
null, "secret", PdfWriter.ALLOW_SCREENREADERS);
// appearance
PdfSignatureAppearance appearance =
stamper.SignatureAppearance;
//appearance.Image = new iTextSharp.text.pdf.PdfImage();
appearance.Reason = "Reason";
appearance.Location = "Location";
appearance.SetVisibleSignature(new
iTextSharp.text.Rectangle(36, 748, 244, 880), 2, "Secure-PDF");
//DateTime signatureDatetime = DateTime.Now;
//appearance.SignDate = signatureDatetime;
// digital signature

MakeSignature.SignDetached(appearance,
externalSignature, chain, null, null, null, 0, CryptoStandard.CMS);
stamper.Close();
stamper.Dispose();
}
}
reader.Close();
reader.Dispose();
}

serversignature class:
class ServerSignature : iTextSharp.text.pdf.security.IExternalSignature
{
public byte[] DigSign { get; set; }

string
iTextSharp.text.pdf.security.IExternalSignature.GetEncryptionAlgorithm()
{
return "RSA";
}

string
iTextSharp.text.pdf.security.IExternalSignature.GetHashAlgorithm()
{
return iTextSharp.text.pdf.security.DigestAlgorithms.SHA1;
}

byte[] iTextSharp.text.pdf.security.IExternalSignature.Sign(byte[]
message)
{
return DigSign;
}
}
}

signed pdf file
TRANSFER_[PROVISIONAL]_29_05_20141.pdf
<http://itext-general.2136553.n4.nabble.com/file/n4660339/TRANSFER_%5BPROVISIONAL%5D_29_05_20141.pdf>



--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4660339.html
Sent from the iText - General mailing list archive at Nabble.com.
mkl
2014-09-05 12:48:53 UTC
Permalink
arnabroy,
Post by arnabroy
same error file corrupted
please help
STEP1: creating the hash of the pdf file in the server
This is wrong. In your original attempt you started by creating a PdfStamper
Post by arnabroy
PdfStamper stamper = PdfStamper.CreateSignature(reader, fout, '\0');
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
...
Stream data = appearance.GetRangeStream();
...
byte[] hash = new byte[messageDigest.GetDigestSize()];
messageDigest.DoFinal(hash, 0);
This was correct (or might be, I'm normally dealing with Java and don't know
the .Net IDigest contract): You have to sign this very document hash and
then insert the CMS signature into this very PdfStampter because the signed
data is more than the bytes of the original PDF file, and even they often
are somewhat rearranged.

For some backgrounds read this Security Stack Exchange answer:
http://security.stackexchange.com/a/35131/16096

Your original attempt failed thereafter by completely messing up the
signature container creation.

The final insertion of the signature container was correct, too
Post by arnabroy
byte[] paddedSig = new byte[8192];
Array.Copy(encodedSig, 0, paddedSig, 0, encodedSig.Length);
PdfDictionary dic2 = new PdfDictionary();
dic2.Put(PdfName.CONTENTS, new
PdfString(paddedSig).SetHexWriting(true));
sap.Close(dic2);
You merely have to correctly create a good detached CMS signature of that
signature inbetween these code fragments.

As mentioned before I generally deal with Java, not C# or JavaScript, and,
therefore, cannot tell how best to create that signature in your
environment.

Regards, Michael



--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4660343.html
Sent from the iText - General mailing list archive at Nabble.com.
arnabroy
2014-09-09 04:27:28 UTC
Permalink
thanks michael.
the problem is resolved.
your detailed observations and pinpointing the key issues has helped me to
resolve the issue.




--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4660351.html
Sent from the iText - General mailing list archive at Nabble.com.
arnabroy
2015-09-29 10:25:10 UTC
Permalink
Hi,
I was not able to solve the problem by hashing at
the client side with CAPICOM javascript.
I solved the problem by using .net at the client
side instead of CAPICOM.

Go through the attached files. Hope, it will
resolve your issue.

(See attached file: PDFSIG.cs)(See attached file:
Default.aspx.cs)(See attached file: Default.aspx)

Thanks & Regards,
Arnab Roy




"mladen
.poptra
jkov To
[via arnabroy
iText]" <***@itc.in>,
<ml-nod cc
e
+s21365 Subject
53n4660 Re: Sign and PDF
902h46@ with SmartCard and
n4.nabb web browser only
le.com>

29-09-2
015
14:36





As you said at the end that the problem has been
resolved, could you please post the final version
of the routine. I can not figure it out how have
you resolved the problem.
Thanks


If you reply to this email, your message will be
added to the discussion below:
http://itext.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4660902.html

To unsubscribe from Sign and PDF with SmartCard
and web browser only, click here.
NAML
Disclaimer:
This Communication is for the exclusive use of the intended recipient(s) and shall not attach any liability on the originator or ITC Ltd./its Subsidiaries/its Group Companies.
If you are the addressee, the contents of this email are intended for your use only and it shall not be forwarded to any third party, without first obtaining written authorization from the originator or ITC Ltd./its Subsidiaries/its Group Companies.
It may contain information which is confidential and legally privileged and the same shall not be used or dealt with by any third party in any manner whatsoever without the specific consent of ITC Ltd./its Subsidiaries/its Group Companies.
If this Email is received in error, please contact the System Administrator of ITC Limited at ***@itc.in by quoting the name of the sender and the Email address to which it has been sent and then delete it.
Please note that ITC Ltd/its subsidiaries/its Group Companies accept no responsibility for viruses and it is your responsibility to scan or otherwise check this Email and any attachments.
Please be advised that Email communications will not result in an agreement binding ITC Ltd/its subsidiaries/its Group Companies. Such contracts should be executed separately and only by managers authorized in this behalf.


PDFSIG.cs (4K) <http://itext.2136553.n4.nabble.com/attachment/4660903/0/PDFSIG.cs>
Default.aspx.cs (18K) <http://itext.2136553.n4.nabble.com/attachment/4660903/1/Default.aspx.cs>
Default.aspx (7K) <http://itext.2136553.n4.nabble.com/attachment/4660903/2/Default.aspx>




--
View this message in context: http://itext.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4660903.html
Sent from the iText mailing list archive at Nabble.com.

mkl
2012-02-09 09:44:06 UTC
Permalink
Max,
Post by madmax
1) removed the date stamps from both the itext and CAPICOM
As mentioned before, thw two signing times are not a problem. The PDF
specification recommends not to use both in the same PDF signature but it
does not forbid it.
Post by madmax
2) Also changed the bDetached parameter value to "false" as suggested by
Michael in the javascript
3) I also noticed that I could avoid getting the digest from the PDF and
just created a signature using the browser and some dummy data that I
could pass. Then I can send it to the server and injecting into the PDF.
I see you're playing around with the CAPICOM SignedData class. I would
suggest you try that in a more systematic manner. What you want (as long as
you use adbe.pkcs7.detached or ETSI.CAdES.detached signatures --- but these
are the recommended ones anyway) are CMS signature containers with a single
signature without encapsulated data; and you have to be able to inject the
already calculated hash which in case of the presence of signed attributes
is to be used as MessageDigest attribute value.

Studying aszomor's code might present an alternative approach.
Post by madmax
BTW, what tools do you guys use to debug the PDF generation with itext?
just the regular Eclipse debugger?
As long as signature container are created (i.e. the problem is not an early
exception) and merely not accepted by the Adobe Reader or some other
relevant verification software, the most important step of my first analysis
is creating an ASN.1 structure dump of the signature container and
inspecting it with the relevant specifications at hand. The outcome thereof
generally makes it quite clear where to look.

Regards, Michael

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4372330.html
Sent from the iText - General mailing list archive at Nabble.com.
madmax
2012-02-03 05:18:15 UTC
Permalink
Hi Michael and Andreas,

I have been trying to figure out what the issue could be based on your
comments.

1) In the JSP I did the following

The alert pops up the cert that was selected then I went into the details
tab and looked at the key usage it shows Digital Signature, Non-Repudiation
(c0) - see screen shot attached

2) Once the digest is signed and I send it back to the servlet I verify it
with some java code And on the console it shows the following:


23:43:26,674 INFO [X509ServletExternalSignature] verifyDigest (begin)...
23:43:26,674 INFO [STDOUT] ***@47d6a49
23:43:26,690 INFO [X509ServletExternalSignature]
CN=HHS-SSP-CA-B7,OU=HHS,O=U.S. Government,C=US,DC=hhs,DC=gov
23:43:26,690 INFO [X509ServletExternalSignature] DC=gov,DC=hhs,C=US,O=U.S.
Government,OU=HHS,CN=HHS-SSP-CA-B7
23:43:26,690 INFO [X509ServletExternalSignature] C=US,O=U.S.
Government,OU=HHS,OU=CDC,OU=People,UID=1111817686+CN=XXXXXX XXXXXXX
(Affiliate)
23:43:26,690 INFO [X509ServletExternalSignature] VERIFIED: true
23:43:26,690 INFO [X509ServletExternalSignature] verifyDigest (end)...
23:43:26,690 INFO [X509ServletExternalSignature] x509 AJAX End call...
3) How can I verify if I have the right padding I am way in over my head at
this point I have attached the Java method I used to verify (cannot take
credit I lifted it from
http://bozhobg.wordpress.com/2009/07/02/how-to-obtain-signers-details-from-a-javascript-signed-data/


I am beginning to wonder if my approach completely wrong in trying to get
itext to give me a digest then return it to the browser which then sings it
with the smart card and returns it back to the server where I inject it back
in the PDF?

When I Googled I could not really everget a definitive answer that this
implementation would actually work. Maybe it’s just not meant to work?

The smartcard is working I just tried to sign a PDF with my smart card using
Adobe professional and the document was signed correctly so it something on
my side butI doubt it’s itext.

Thanks again,

max


Loading Image...
2-2-2012_23-59-17.png
http://itext-general.2136553.n4.nabble.com/file/n4353711/verifyDigestt.java
verifyDigestt.java

--
View this message in context: http://itext-general.2136553.n4.nabble.com/Sign-and-PDF-with-SmartCard-and-web-browser-only-tp4319344p4353711.html
Sent from the iText - General mailing list archive at Nabble.com.
Andreas Kuehne
2012-02-08 07:55:39 UTC
Permalink
Hi max,

could you please forward the signed PDF?

Greetings
Andreas

----- original Nachricht --------

Betreff: Re: [iText-questions] Sign and PDF with SmartCard and web browser only
Gesendet: Mi, 08. Feb 2012
Von: madmax

Hi MichaelI looked a little dipper to what you were saying and begun looking closer to my â&#128;&#156;verifyâ&#128; method and it dawned on me that I had seen similar code from an example of detached signature and using BouncyCastle (source: http://itextpdf.sourceforge.net/howtosign.html#signextdiccms
I rewrote the code to inject the signature as follows:
private void signPdf(String path, String fileName, String digest, HttpServletRequest request) {HttpSession session = request.getSession();PdfStamper stamper;PdfSignatureAppearance appearance;stamper = (PdfStamper) session.getAttribute("stamper");appearance = stamper.getSignatureAppearance();byte[] hash = ((String) session.getAttribute("hash")).getBytes();log.info("signPdf with Digest(begin)...");try {// String content = (String) session.getAttribute("hash");int csize = 15000;byte[] data = Base64.decodeBase64(digest.trim().getBytes());Security.addProvider(new BouncyCastleProvider()); CMSSignedData signedData = new CMSSignedData(data); byte[] pk = signedData.getEncoded();byte[] outc = new byte[csize];PdfDictionary dic2 = new PdfDictionary();System.arraycopy(pk, 0, outc, 0, pk.length);dic2.put(PdfName.CONTENTS, new PdfString(outc).setHexWriting(true));appearance.close(dic2);}catch (IOException e) {e.printStackTrace();}catch (DocumentException e) {e.printStackTrace();}catch (Exception e) {e.printStackTrace();}log.info("signPdf with Digest (end)...");}
I am almost there adobe is no longer crashing when I look at the signature, but when I try to verify it says â&#128;&#156;the document has been altered or corrupted since the signature was appliedâ&#128; see attached jpg.

Is this related to a datetime stamp issue between the servlet reserving the space for the digest and the browser creating the signature a few second apart? Do you know how I could fix resolve this

Thanks again,

max

2-8-2012_00-36-22.png
2-8-2012_00-35-18.png
2-8-2012_00-34-28.png
View this message in context: Re: Sign and PDF with SmartCard and web browser only
Sent from the iText - General mailing list archive at Nabble.com.


--- original Nachricht Ende ----
Loading...