【问题标题】:Reading a pfx file from usb token with java使用 java 从 usb 令牌中读取 pfx 文件
【发布时间】:2014-10-05 02:50:44
【问题描述】:

我正在尝试使用 USB 电子令牌在 java 中签署 pdf 文档。我想从 USB 令牌安全网 (alladin etoken pro 72 k(Java)) 读取签名并使用 java 代码附加到 pdf。我有使用存储在本地计算机中的密钥完成数字签名签名。但我想知道如何使用 USB 电子令牌完成相同的操作。

【问题讨论】:

  • 您不是“从 USB 令牌读取 PFX”,而是使用该令牌执行加密操作(文档哈希的签名)。现在,有 iText(检查许可证!)还有我们的 SecureBlackbox 产品,它们都支持使用存储在硬件设备上的证书和私钥对 PDF 文档进行签名。
  • 我如何使用存储在 USB 令牌中的密钥来使用 java 签署 pdf 文档。如果密钥存储在我的本地计算机中,我可以在我的 java 代码中给出该密钥的位置。但是如果密钥存储在 USB 令牌中我如何在我的代码中给出该密钥位置。
  • 这取决于你使用什么代码。如果您使用上述库之一,请查看其文档。如果您已经编写了自己的 PDF 签名代码,那么您需要使用 PKCS11 API 来访问硬件。

标签: java digital-signature pfx pkcs#12 e-token


【解决方案1】:

用于签名的 USB 令牌的全部意义在于,没有人可以从该设备读取密钥。因此,您将哈希发送到令牌,令牌会将签名发回给您。

为此,您需要一个可以与令牌对话的 JCE 提供者。这通常由 PKCS#11(令牌为此提供库)或令牌提供 MSCAPI 驱动程序(在 windows 下)完成。

两者都可以在 Java 下使用,PKCS#11 方式的设置可能有点复杂,但根据我的经验,自动签名更好,因为在 MSCAPI 情况下,您经常需要手动输入令牌 PIN。

如果您的令牌被 Windows 识别,以下命令应该会看到并列出其密钥:

keytool -list -storetype Windows-MY

然后可以使用 Windows 密钥库来获取用于签名的密钥句柄,但您也可以使用它来导出公钥的副本。

【讨论】:

    【解决方案2】:

    您可以使用 SUN PKCS11 提供程序来引用 Etoken 中的密钥。您可以尝试以下代码

    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("pkcs11Config");
        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 keyStore=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);
    
        }
    

    【讨论】:

      【解决方案3】:

      试试这个代码

       import com.lowagie.text.pdf.*;
       import com.lowagie.text.Rectangle;
       //import com.lowagie.text.pdf.pdfSignatureAppearance;
       //import com.lowagie.text.pdf.pdfStamper;
       import java.security.*;
       import java.io.*;
       import java.awt.*;
       import java.security.cert.*;
       import java.lang.*;
      
       import java.io.FileInputStream;
       import java.security.KeyStore;
       import java.security.cert.CertPath;
       import java.security.cert.CertificateFactory;
       import java.util.ArrayList;
       import java.util.List;
      
      
      
      public class pdfsign1{
        public static void main(String args[]) {
      try {
      KeyStore ks = KeyStore.getInstance("pkcs12");
      ks.load(new FileInputStream("my_private_key.pfx"), "my_password".toCharArray());
      String alias = (String)ks.aliases().nextElement();
      PrivateKey key = (PrivateKey)ks.getKey(alias, "my_password".toCharArray());
      Certificate[] chain = ks.getCertificateChain(alias);[/b]
      PdfReader reader = new PdfReader("original.pdf");
      FileOutputStream fout = new FileOutputStream("signed.pdf");
      PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0');
      PdfSignatureAppearance sap = stp.getSignatureAppearance();
      //sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
      sap.setReason("I'm the author");
      sap.setLocation("Lisbon");
      // comment next line to have an invisible signature
      sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
      stp.close();
        }
      catch(Exception e) {}
      }
      }
      

      【讨论】:

      • 这假定文件输入不是令牌。
      • 答案与令牌无关。它是关于使用 PKCS12 格式的密钥库文件。
      猜你喜欢
      • 2013-12-10
      • 2011-05-29
      • 1970-01-01
      • 2012-09-08
      • 1970-01-01
      • 2012-11-21
      • 2013-02-14
      • 1970-01-01
      • 2018-03-23
      相关资源
      最近更新 更多