Quantcast

Sign and PDF with SmartCard and web browser only

classic Classic list List threaded Threaded
42 messages Options
123
mkl
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

mkl
Max, Andreas,
Andreas Kuehne-3 wrote
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

madmax
This post was updated on .
In reply to this post by Andreas Kuehne-3
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
var FilteredCertificates = MyStore.Certificates.Find(CAPICOM_CERTIFICATE_FIND_KEY_USAGE, CAPICOM_DIGITAL_SIGNATURE_KEY_USAGE);
alert(Signer.Certificate.Display())
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] org.bouncycastle.cms.CMSSignedData@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 (I 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 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?

When I Googled I could not really ever get a definitive answer or direction that this implementation would actually work. I think capicom activex is either on the way out or has alredy been depracated by Microsoft. Maybe it’s just not meant to work?

But what is the alternative? (applet, activex, HSM)

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

verifyDigestt.java

2-2-2012_23-59-17.png
mkl
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

mkl
Max,
madmax wrote
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] org.bouncycastle.cms.CMSSignedData@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... 
Your verifying Java code:
    byte[] data = Base64.decodeBase64(digest.trim().getBytes());

    Security.addProvider(new BouncyCastleProvider());  
    CMSSignedData signedData = new CMSSignedData(data); 
    System.out.println(signedData);
    [...]
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!
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.
But what is the alternative? (applet, activex, HSM)
That would depend on the details of the requirements of your project.

Regards,   Michael
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

madmax
Hi Michael
Thanks again for your suggestion. As I parse through your response you say:
mkl wrote
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

madmax
This post was updated on .
Hi Michael,

I looked a little further 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
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 “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

2-8-2012_00-36-22.png
2-8-2012_00-35-18.png
2-8-2012_00-34-28.png
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

Andreas Kuehne-3
In reply to this post by madmax
MessageHi 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 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
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 “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

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 ----

------------------------------------------------------------------------------
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
[hidden email]
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
mkl
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

mkl
In reply to this post by madmax
Max,
madmax wrote
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.
if so how do you tell itext to embed the signature directly without using PdfPKCS7
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());
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
mkl
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

mkl
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...

mkl wrote
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

madmax
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

signed-sample-1.pdf
original-sample-1.pdf
madmax-sig.jpg
X509ServletExternalSignature.java
x509ExternalSig.jsp
mkl
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

mkl
Max,
madmax wrote
In the signPdf method the sample Java code has reduced the code to:
byte[] data= Base64.decodeBase64(digest.trim().getBytes());
The data you received like that and then inserted in the PDF definitively is a signature container.
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.
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

Andreas Kuehne-3
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

> Max,
>
> madmax wrote
>> In the signPdf method the sample Java code has reduced the code to:
>> byte[] data= Base64.decodeBase64(digest.trim().getBytes());
> The data you received like that and then inserted in the PDF definitively is
> a signature container.
>
>> 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.
>
>> 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
> [hidden email]
> 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: [hidden email]

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


------------------------------------------------------------------------------
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
[hidden email]
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

madmax
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:
SignedData.Content = "Some dummy data";
....
var szSignature = SignedData.Sign(Signer, true, CAPICOM_ENCODE_BASE64);

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

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

aszomor
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/



------------------------------------------------------------------------------
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
[hidden email]
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
mkl
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

mkl
In reply to this post by madmax
Max,
madmax wrote
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.
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.
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

Raffaele
In reply to this post by aszomor
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

aszomor

sap.CertificationLevel = PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED;
beore sgn.SetExternalDigest

Idézet (Raffaele <[hidden email]>):

> 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.
>
> ------------------------------------------------------------------------------
> 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
> [hidden email]
> 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
>


------------------------------------------------------------------------------
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
[hidden email]
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

Raffaele
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.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

aszomor
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);
     }
}





------------------------------------------------------------------------------
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
[hidden email]
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
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

Raffaele
None of the examples as solved the problem!!!

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



Any suggestion???

Thanks
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate
star

Re: Sign and PDF with SmartCard and web browser only

Leonard Rosenthol-3
In reply to this post by Raffaele
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:[hidden email]]
Sent: Thursday, February 09, 2012 9:55 AM
To: [hidden email]
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
[hidden email]
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

------------------------------------------------------------------------------
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
[hidden email]
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
123
Loading...