Sign with USB Token

I want to sign a pdf document with GroupDocs Java, how can I complete this with Groupdocs Java library ?

1 Like

@trunkey2003

Please let us know which types of signatures you would like to use with the GroupDocs.Signature for Java API. You have a range of options available, including but not limited to digital signatures, text-based signatures, form-field signatures, and image-based signatures. By specifying your requirements, we can provide you with the necessary assistance tailored to your needs.

1 Like

@atir.tahir
I would like to sign with a Digital signature with my USB Token

@trunkey2003
We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.

Issue ID(s): SIGNATUREJAVA-2701

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.

1 Like

Hi, @trunkey2003
Thank you for your interest in the Signature product. Please be aware that GroupDocs.Signature for Java is a standalone library that works with the given document and creates inside the document different signature artifacts like Text, Image, Barcode, QRCode, Digital, Form Field, Stamps
The Digital signature could be added to the document from the PFX Digital Certificate file format. This is the only way a digital signature could be added.
GroupDocs.Signature does not support external USB Tokens, same as any external devices because there are a lot of implementation standpoints and permission issues that could bring while accessing your hardware.
Usually, this is related to special software that uses SDK of the particular devices list.

If you can extract PFX file from your USB Token then the digital certificate is possible.
Also please be aware that mostly USB Token contains specific key or signature thumbprint but not a PFX digital certificate file when the digital document signing requires exact PCK12 format PFX.

Hope this will help to find best solution.
Please share if we can help more somehow.

1 Like

@atir.tahir @yuriy.mazurchuk
Thank you for your support

1 Like

@trunkey2003

You are welcome.

1 Like

Hello,

I’m not agree with you. You can use usb device with the CCID profile. Actually, all OS (Windows, MacOS, Linux) support usb CCID profile. This profile allow any computer to access digital certificate stored on a smartcard or usb plug without the need of any additional drivers.

If you plug this kind of usb device in windows, the certificate stored on the device is directly added to the windows keystore and you can use it from any application.

Regards

Stéphane GINER

Hello @sginer !

Thank you for this great idea!

We will try to investigate this opportunity within the next few days and get back to you ASAP!
Our internal ticket ref SIGNATUREJAVA-2759 and SIGNATURENET-4877.
We will get back to you with the investigation results.

Hello,

I done some tests, and we can’t sign documents because we can’t create PKCS#12 keystore with a wrapped certificate of a smart card.

Have you got an API who can sign pdf docs with java java.security.PrivateKey interface ?

I think you already extract PrivateKey object to sign doc in your API. It will be fine if you make a public sign function with PrivateKey object

Regards

Stéphane GINER

Hello, @sginer

Thank you for the update!

During this month we will publish new GroupDocs.Signature for Java release with a few changes that potentially could help you with your needs.

Let me share a few investigation results.
If your USB device driver implements Certificate Propagation Service (Certificate Propagation Service - Windows Security | Microsoft Learn) that should be part of CCID (from my understanding) then OS should ask you to migrate stored certificates to OS Key Store

SignWithDigitalAdvancedSpreadSheets.zip (1.2 KB)

In 23.10 release this was implemented in GroupDocs for .Net

and later this month we will publish the same feature for the Java release.

We will keep you posted with the updates within this and further weeks!
Thank you!

Hello

I saw that you set the sign with pkcs#12 in your latest release (24.3).
I have done a short program to test it but I think I don’t use the right api.

Could you give me a sample program that can show me how to use smart card certificate ?

I give you the program I made

I alwais had this error message

“Certificate #1 is not suitable for signing. Perhaps it does not have exportable private key”

Regards

Stéphane GINER

package ch.ge.pj.keystore;

import java.io.File;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import com.groupdocs.signature.Signature;
import com.groupdocs.signature.domain.SignResult;
import com.groupdocs.signature.domain.signatures.DigitalSignature;
import com.groupdocs.signature.domain.signatures.StoreName;
import com.groupdocs.signature.options.sign.DigitalSignOptions;


public class MainSignPDFGroupDocs {
    /**
    * Sign document with digital signatures got from one of certificate stores
    */
    public static void main(String[] args) {
        System.out.println("--------------------------------------------------------------------------------------------------------------------");
        System.out.println("[Example Advanced Usage] # SignWithDigitalUsingCertificateStore : Sign document with digital signatures got from one of certificate stores");

        //The document to be signed.
        String filePath = "D:\\Java\\WindowsKeystore\\test\\pdf\\pdfTestInput.pdf";

        List<DigitalSignature> signatures = new ArrayList<DigitalSignature>();
        try {
            //Get digital signatures from common storage
            //If such storage does not exist at your system an exception will be thrown
            List<DigitalSignature> signaturesMy =
                    DigitalSignature.loadDigitalSignatures(StoreName.My);
            signatures.addAll(signaturesMy);
        } catch (Exception e) {
            System.out.println("Something wrong with your certificates storage");
        }

        int signatureNumber = 0;
        //sign document with all signatures
        for (DigitalSignature digitalSignature : signatures) {
            signatureNumber++;
            String outputFilePath =
                    new File("D:\\Java\\WindowsKeystore\\test\\pdf\\",  "SignWithDigitalUsingCertificateStore\\digitallySigned_"+signatureNumber+".pdf").getPath();
            try{
                Signature signature = new Signature(filePath);
                {
                    //Only certificates with private key are good for digital signing
                    KeyStore store = digitalSignature.getCertificate();
                    Enumeration<String> aliasEnum = store.aliases();
                    while (aliasEnum.hasMoreElements()) {
                    	String alias = aliasEnum.nextElement();
                    	System.out.println("Alias : " + alias);
                    	
                    }
                    //Receive a certificate indicating alias(name) for signing.
                    //KeyStore.Entry entry =  store.getEntry("Giner Stephane JPLTTO", null);
                    KeyStore.Entry entry =  store.getEntry("Stéphane GINER", null);
                    if(entry != null) {
                        try {
                            DigitalSignOptions options = new DigitalSignOptions();
                            //options.setPassword(password);
                            options.setSignature(digitalSignature);
                            // digital certificate details
                            options.setReason("Approved");
                            options.setContact("John Smith");
                            options.setLocation("New York");


                            SignResult signResult = signature.sign(outputFilePath, options);
                            System.out.println("Source document signed successfully with " + signResult.getSucceeded().size() + " signature(s).\nFile saved at " + outputFilePath + ".");

                        } catch (Exception ex) {
                            System.out.println("Certificate #" + signatureNumber + " is not suitable for signing. Perhaps it does not have exportable private key.");
                        }
                    }
                }
            }catch (Exception e){
                System.out.println(e.getMessage());
            }
        }
    }    
}

Hello, @sginer

We are trying to reproduce the issue on our side.
Working with the imitation on the Smart Device could be a little tricky.
Can you please share as much information and details as possible - for example if there’s an ability to export your certificate as pfx and send it to us?
Meanwhile, we will check on our end and get back.
Thank you!

Hello,

As you can see in the error message, my private key cannot be taken out of the smart card. The hash must be calculated by your API and passed to the smart card to allow it to internally sign the hash.

My code example is derived from one of your examples. Do you think I’m using the API correctly and the problem is a bug?

Greetings

Stéphane GINER

Hello

Have you got some news ?

Regards

Stéphane GINER

Hello @sginer

Let me share the good news - a few days ago we implemented PDF Java support for private/public data certificate extraction from external storage. This ability allows us to release very soon the new GroupDocs.Signature for Java release and share updates and examples with you!

Thank you!

hello

Great news.
Could you give me a sample code to show how to use the library ?

Regards

Stéphane GINER

Hello @sginer

Check the updated java version GroupDocs.Signature for Java 24.7
https://releases.groupdocs.com/java/repo/com/groupdocs/groupdocs-signature/24.7/

Please take a look at the release notes and example

You mentioned earlier that you can get the private key from your USB token, right?
so I hope with this part you can proceed.

Our next step within a few weeks will be the implementation of the ability to obtain the private key part over standard system methods but I am afraid it will force the appearance of additional popup with the password (based on your device drivers)

Can you please specify the exact USB Token model?

Thank you!

Hello

I do some tests and it work fine, but I have some points to raise :

  • when the digital signs apply we must imput pin code twice
  • the local time of the computer is used to put the date. Can it be possible to define a specific timestamp service like http://tsa.pki.admin.ch/tsa

For the device I use, I have two :slight_smile:

  • HID OMNIKEY 6121 with a gemplus smartcard
  • Yubikey 5C NFC with an uploaded self signed certificate generated from Yubikey tool.

Regards

Stéphane GINER

Hi @sginer !

I am glad we could help you!

The link you provided is not accessible http://tsa.pki.admin.ch/tsa for us. Mb due to Geo IP limitation. However you can find in the PdfDigialSignature the TimeStamp structure that applies to the PdfDigitalSignature object .

I will check about the twice request pin later this week.
Thank you!