Duc Nhan Do
Duc Nhan Do

Reputation: 3

Digital signatures invalid when I use the iTextSharp

This is my Form -

enter image description here

Following are the code -

private void btnSign_Click(object sender, EventArgs e)
{   
    string sbase64 = richTextBox2.Text;
    byte[] bytes = System.Convert.FromBase64String(sbase64);
    PdfReader reader = new PdfReader("F:\\test1.pdf"); 
    FileStream os = new FileStream("F:\\output.pdf", FileMode.Create);
    IExternalSignatureContainer external1 = new MyExternalSignatureContainer(bytes);
    MakeSignature.SignDeferred(reader, "Signature1", os, external1);
    reader.Close();
    os.Close(); 
}


First, I prepare a PDF file (test.pdf) to create a signed area on a PDF file. Then output the file test1.pdf and string SHA-256.

Next I use the SHA-1 string that is uploaded to the server for signing. The server returns a base64 string.

I copy that base64 and paste it into richtextbox2 to sign and export "output.pdf" file.

Then I check that file "output.pdf" on Foxit Reader (version 10.0), the signature is VALID.

But when I check that file on Adobe Reader or Adobe Acrobat, the signature is INVALID.

Even on Foxit Reader ( latest version 10.1), the signature is invalid. What happened???

I'm not very good at English. Sorry!

UPDATE - ERROR !!!

This is file "output.pdf" when I check on Foxit Reader 10.0 (It's valid) -

enter image description here

And this is when I check on Adobe Acrobat (It's invalid) -

enter image description here

UPDATE... Is there any mistakes?? PKCS#1 or PKCS#7

Upvotes: 0

Views: 1560

Answers (1)

mkl
mkl

Reputation: 96009

There are at least two issues in your example PDF, and they are caused less by your iText related code but more by your signing service or the way you address it.

The Issues

Mixed Digest Algorithms Used

You use SHA-256 to calculate the digest of the signed PDF byte ranges. Thus, the hash algorithm stored in the SignerInfo is SHA-256. As signature/encryption algorithm it only refers to RSA. But in the signature bytes explicitly SHA-1 is used.

This is a bug, according to RFC 5652 that hash algorithm shall be used both for hashing the message data and the signed attributes.

This is a dump of the SignerInfo object

. . . . SEQUENCE {
. . . . . INTEGER 1
. . . . . [...SID...]
. . . . . SEQUENCE {
. . . . . . OBJECT IDENTIFIER sha-256 (2 16 840 1 101 3 4 2 1)
. . . . . . . (NIST Algorithm)
. . . . . . NULL
. . . . . . }
. . . . . [0] {
. . . . . . SEQUENCE {
. . . . . . . OBJECT IDENTIFIER contentType (1 2 840 113549 1 9 3)
. . . . . . . . (PKCS #9)
. . . . . . . SET {
. . . . . . . . OBJECT IDENTIFIER data (1 2 840 113549 1 7 1)
. . . . . . . . . (PKCS #7)
. . . . . . . . }
. . . . . . . }
. . . . . . SEQUENCE {
. . . . . . . OBJECT IDENTIFIER messageDigest (1 2 840 113549 1 9 4)
. . . . . . . . (PKCS #9)
. . . . . . . SET {
. . . . . . . . OCTET STRING    
. . . . . . . . . 2F AA 90 5F A3 3B 2E 74    /.._.;.t
. . . . . . . . . 3F 78 7A C1 85 F8 EF B7    ?xz.....
. . . . . . . . . 20 AE 73 2B F4 2F B2 80     .s+./..
. . . . . . . . . 87 3C 24 50 F9 A8 3F 8B                            
. . . . . . . . }
. . . . . . . }
. . . . . . }
. . . . . SEQUENCE {
. . . . . . OBJECT IDENTIFIER rsaEncryption (1 2 840 113549 1 1 1)
. . . . . . . (PKCS #1)
. . . . . . NULL
. . . . . . }
. . . . . OCTET STRING    
. . . . . . [...Signature Bytes...]
. . . . . }
. . . . }

You can easily recognize the SHA-256 and RSA OIDs; these were added by the iText class PdfPKCS7 based on your inputs.

And this is a dump of the decrypted DigestInfo object in your signature bytes:

SEQUENCE (2 elem) {
. SEQUENCE (2 elem) {
. . OBJECT IDENTIFIER 1.3.14.3.2.26 sha1 (OIW)
. . NULL
. . }
. OCTET STRING (20 byte) AD002EA501871117250DE3BF42D51B4FD2B1C5A0
. }

You can clearly see the SHA-1 OID; furthermore, the 20 bytes hash value is a possible SHA-1 hash but not a SHA-256 hash.

Apparently the sign service created a SHA1withRSA signature in response to your request.

Incorrect Signed Hash Value

As you can see in the decrypted DigestInfo object dump above, the signed hash value is

AD002EA501871117250DE3BF42D51B4FD2B1C5A0

But even if one assumed mixed algorithm usage as mentioned above is ok, this value is incorrect, the correct SHA-1 hash value of the signed attributes in your SignerInfo is

851AD7BF24D159C02A705FD4ABB20EBA9DE2AD2B

This mismatch actually is no surprise, considering that you only sent a SHA-256 digest to the signing service. Probably the service only used some 20 byte part of your 32 byte SHA-256 digest value, or it used your input as the plain data to sign and hashed it.

Follow-ups

In an answer LBMinh asked

1/ Can I change my digest algorithms to SHA1 and send to signing server?

2/ If the signing server used my input as plain data, can I send raw data (no hash) to it?

3/ Why when I check the output pdf with Foxit reader (10.0), it says valid, but in newest version of Foxit or Adobe, it says invalid.

Changing Algorithms

1/ Can I change my digest algorithms to SHA1 and send to signing server?

Of course you can use SHA-1 instead of a SHA-2 variant, simply switch the algorithm name strings in your code.

But you shouldn't. SHA-1 in the context of PDF signing has been shown to be broken, see shattered.io, and as a consequence internationally is considered deprecated. So unless you only sign documents that don't require a signature for anything, switching to SHA-1 is a bad idea. No one in his right mind will trust a document signed with SHA-1 hashing unless it is extremely unimportant.

Instead you should investigate how to request signatures based on SHA-2 hashing from your signing service or switch to a different service.

Sending Raw Data

2/ If the signing server used my input as plain data, can I send raw data (no hash) to it?

If it uses your input as not-yet-hashed data to sign, that quite likely is a good option to investigate. In btnPreparePDF_Click simply don't digest the byte[] sh but use its contents as-is.

Why Does Foxit 10 Say It's Valid?

3/ Why when I check the output pdf with Foxit reader (10.0), it says valid, but in newest version of Foxit or Adobe, it says invalid.

As I showed above in the section "The Issues" the signature is broken. Thus, if some validator says the signature is valid, you are witness of a serious security bug in it.

Apparently Foxit has already recognized that bug and fixed it in their newest version.


Side Notes

Is there any mistakes?? PKCS#1 or PKCS#7

With a comment "I found a few mistakes" you added the following image to your question

RSA with PKCS#1 v.1.5

No, this is no mistake, "RSA with PKCS#1 v.1.5" is short for "RSASSA with PKCS#1 v1.5 padding" aka RSASSA-PKCS1-v1_5.

There essentially are two relevant signing schemes based on the RSA algorithm, RSASSA-PKCS1-v1_5 and RSASSA-PSS.

RSASSA-PKCS1-v1_5 is the older scheme which is very simple and has some questionable security properties.

RSASSA-PSS is the newer scheme which is more complex and does not have those questionable security properties.

Future-proof software based on the RSA algorithm should, therefore, use RSASSA-PSS.

For details of those signing schemes see RFC 8017.

Upvotes: 2

Related Questions