2016-06-21 78 views
2

我嘗試使用java api添加數字簽名到pdf,並且簽名被epass2003令牌讀取。所以,在這裏我完成了這項工作(將數字簽名添加到pdf), 及其工作正常,但是當我在另一個系統中打開這個pdf文檔時,它顯示 「Atleast one signature has problem」,在我的系統中,請幫助我。我在下面附上了我的代碼,請找到它。使用java api和epass2003令牌的pdf數字簽名

public class Test { 
    public static void main(String args[]) throws IOException, GeneralSecurityException, DocumentException, CertificateVerificationException{ 
    // Create instance of SunPKCS11 provider 

    String userFile = "C:/results/test.pdf"; 
    String userFile_signed = "C:/results/test_signed.pdf"; 

    String pkcs11Config = "name=eToken\nlibrary=C:\\Windows\\System32\\eps2003csp11.dll"; 
    java.io.ByteArrayInputStream pkcs11ConfigStream = new java.io.ByteArrayInputStream(pkcs11Config.getBytes()); 
    sun.security.pkcs11.SunPKCS11 providerPKCS11 = new sun.security.pkcs11.SunPKCS11(pkcs11ConfigStream); 
    java.security.Security.addProvider(providerPKCS11); 

    // Get provider KeyStore and login with PIN 
    String pin = "12345678"; 
    java.security.KeyStore keyStore = java.security.KeyStore.getInstance("PKCS11", providerPKCS11); 
    keyStore.load(null, pin.toCharArray()); 

    // Enumerate items (certificates and private keys) in the KeyStore 
    java.util.Enumeration<String> aliases = keyStore.aliases(); 
    String alias = null; 
    while (aliases.hasMoreElements()) { 
     alias = aliases.nextElement(); 
     System.out.println(alias); 
    } 

    PrivateKey pk = (PrivateKey)keyStore.getKey(alias, "12345678".toCharArray()); 
     Certificate[] chain = keyStore.getCertificateChain(alias); 
     OcspClient ocspClient = new OcspClientBouncyCastle(); 
     TSAClient tsaClient = null; 
     for (int i = 0; i < chain.length; i++) { 
      X509Certificate cert = (X509Certificate)chain[i]; 
      String tsaUrl = CertificateUtil.getTSAURL(cert); 
      if (tsaUrl != null) { 
       tsaClient = new TSAClientBouncyCastle(tsaUrl); 
       break; 
      } 
     } 
     List<CrlClient> crlList = new ArrayList<CrlClient>(); 
     crlList.add(new CrlClientOnline(chain)); 
     Test t = new Test(); 
     t.sign(userFile, userFile_signed, chain, pk, DigestAlgorithms.SHA256, providerPKCS11.getName(), 
        CryptoStandard.CMS, "Test", "Signature", crlList, ocspClient, tsaClient, 0); 
} 
public void sign(String src, String dest, 
     Certificate[] chain, PrivateKey pk, 
     String digestAlgorithm, String provider, CryptoStandard subfilter, 
     String reason, String location, 
     Collection<CrlClient> crlList, 
     OcspClient ocspClient, 
     TSAClient tsaClient, 
     int estimatedSize) 
       throws GeneralSecurityException, IOException, DocumentException { 
    // Creating the reader and the stamper 
    PdfReader reader = new PdfReader(src); 
    FileOutputStream os = new FileOutputStream(dest); 
    PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0'); 
    // Creating the appearance 
    PdfSignatureAppearance appearance = stamper.getSignatureAppearance(); 
    appearance.setReason(reason); 
    appearance.setLocation(location); 
    appearance.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, "sig"); 
    // Creating the signature 
    ExternalSignature pks = new PrivateKeySignature(pk, digestAlgorithm, provider); 
    ExternalDigest digest = new BouncyCastleDigest(); 
    MakeSignature.signDetached(appearance, digest, pks, chain, crlList, ocspClient, tsaClient, estimatedSize, subfilter); 
} 
} 

以上是我的代碼請幫幫我。

+0

請分享與該令牌簽名的樣本文件進行分析...... *當我在另一個系統中打開此pdf文檔時,它顯示「至少有一個籤​​名有問題」,在我的系統中正確驗證簽名* - 聽起來像當您使用在您的機器上授予信任的令牌時,令牌標誌不被普遍信任的證書(即其發行者不在AATL或EUTL上)。 – mkl

+0

嗨感謝您的回覆,並且您可以在下面的鏈接下載示例簽名文件,請找到它https://drive.google.com/file/d/0B6t6f1VKlju5UTBheVA3S25VY1k/view?usp=sharing –

+0

請分享完整的代碼庫轉儲。我們也在尋找相同的工作解決方案。 –

回答

1

望着簽名屬性人們看到:

Signature Properties window

此對話框狀態問題:

,因爲它沒有被包含在受信任的證書列表中的簽名者的身份不明並且它的父證書都不是可信證書。

而且一看簽名的證書顯示:

Certificate viewer window

因此,你的代碼只嵌入簽名證書本身,而不是它的證書路徑(否則他們將在證書查看器窗口中顯示已)。不幸的是,頒發者證書(用於RCAI Class 2 2014的SafeScrypt sub-CA)並不是立即可信的,該證書的頒發者(SafeScrypt CA 2014)也不是,而是該證書的頒發者(CCA India 2014)。

最有可能在您的計算機上,整個證書鏈都是已知的,或者至少是明確信任的證書。

要在其他只知道根證書的計算機上獲得相同的效果,只需將「SafeScrypt sub-CA for RCAI Class 2 2014」和「SafeScrypt CA 2014」的證書添加到您的Certificate[] chain

+0

感謝您的回覆先生,並在我的代碼while循環別名時,它將只打印一個別名:「VIBIN SRINIVAS KL的SafeScrypt sub-CA for RCAI Class 2 2014 ID」,那麼如何添加另一個別名以證書[]鏈。但在我的證書查看器窗口顯示所有根證書我已附加圖片鏈接請找到它 - https://drive.google.com/file/d/0B6t6f1VKlju5UnR5ajhNdHllQ0U/view?usp =共享,請幫助我 –

+0

*如何將另一個別名添加到證書[]鏈* - 您不會向證書鏈添加別名,而是添加證書。由於看起來你的令牌不提供這些證書,你可以從你的提供者下載它們,將它們加載到你的代碼中,然後將它們添加到你從'keyStore.getCertificateChain(alias)'得到的證書中。關於圖片:點擊鏈接我被告知我沒有閱讀它所需的權限。 – mkl

+0

sory使用此鏈接-https://drive.google。com/file/d/0B6t6f1VKlju5UnR5ajhNdHllQ0U/view?usp = sharing –