首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无需两次输入个人识别码即可对iText进行数字签名

无需两次输入个人识别码即可对iText进行数字签名
EN

Stack Overflow用户
提问于 2012-07-20 00:06:17
回答 1查看 2.8K关注 0票数 0

我正在尝试使用智能卡和iText对PDF进行数字签名。我通读了有关如何使用iText对文档进行签名的documentation,并亲自尝试使用其中的一些代码。下面是我使用的代码:

代码语言:javascript
复制
String pkcs11ConfigSettings =
  "name = SmartCard\nlibrary = C:\\Program Files\\ActivIdentity\\ActivClient\\acpkcs201-ns.dll";
AuthProvider p =
  new SunPKCS11(new ByteArrayInputStream(pkcs11ConfigSettings.getBytes()));
Security.addProvider(p);
KeyStore.PasswordProtection pp =
  new KeyStore.PasswordProtection("012345".toCharArray());
KeyStore.Builder builder =
  KeyStore.Builder.newInstance("PKCS11",p ,pp);
KeyStore ks = builder.getKeyStore();
Certificate[] cc = ks.getCertificateChain("Digital Signature Key");
PrivateKey pk = (PrivateKey)ks.getKey("Digital Signature Key", null);
OutputStream fos = new FileOutputStream("c:\\2.pdf");
PdfReader reader = new PdfReader(new FileInputStream(new File("C:\\1.pdf")));
PdfStamper stamper = PdfStamper.createSignature(reader, fos, '\0');
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setCrypto(pk, cc, null,PdfSignatureAppearance.SELF_SIGNED);
appearance.setVisibleSignature(new Rectangle(0, 0, 100, 100), 1,null);
stamper.close();

这种方法的问题是,当iText关闭PDFStamper时,它会调用C_Sign(),然后调用驱动程序的提示输入PIN码。

因此,如果这是一个应用程序,它将要求我在签名之前输入我的个人识别码,以便获得KeyStorePrivateKey,以及当司机的个人识别码输入提示出现时。有没有两次索要PIN的方法?我是个新手,我是不是走错路了?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-07-24 01:04:53

似乎如果我按照authenticated attributes的例子操作,每次签署文档时,PIN码对话框只会弹出一次。这是我最终使用的最后一段代码,希望能对其他人有所帮助。

代码语言:javascript
复制
for(int i=0;i<2;i++) {
    String pkcs11ConfigSettings =
                "name = AuthProvider\nlibrary = C:\\Program Files\\ActivIdentity\\ActivClient\\acpkcs201-ns.dll";
    AuthProvider p = (SunPKCS11)Security.getProvider("SunPKCS11-AuthProvider");
    if(p==null) {
        p = new SunPKCS11(new ByteArrayInputStream(pkcs11ConfigSettings.getBytes()));
        p.setCallbackHandler(new CallbackHandler() {    
            @Override
            public void handle(Callback[] callbacks) throws IOException,
                    UnsupportedCallbackException {
                for(Callback c : callbacks)
                    if(c instanceof PasswordCallback) {
                        //HACK. if we set password to null it will bring up the drivers PIN dialog.
                        ((PasswordCallback) c).setPassword(null);
                    }
            }
        });
        Security.addProvider(p);
    }
    KeyStore ks = KeyStore.getInstance("PKCS11",p); 
    ks.load(null, null);
    Certificate[] cc = ks.getCertificateChain("Digital Signature Key");
    PrivateKey pk = (PrivateKey)ks.getKey("Digital Signature Key", null);
    OutputStream fos = new FileOutputStream("c:\\doc" + i + ".pdf"); ;
    PdfReader reader = new PdfReader(new FileInputStream(new File("C:\\1.pdf")));
    PdfStamper stamper = PdfStamper.createSignature(reader, fos, '\0');
    PdfSignatureAppearance sap = stamper.getSignatureAppearance();
    sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
    Calendar cal = Calendar.getInstance();
    PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
    dic.setDate(new PdfDate(cal));
    dic.setName(PdfPKCS7.getSubjectFields((X509Certificate)cc[0]).getField("CN"));
    sap.setCryptoDictionary(dic);
    sap.setLayer2Text("Digitally signed by "+ dic.get(PdfName.NAME) +"\n\nDate: " + cal.getTime().toString());
    HashMap<PdfName,Object> exc = new HashMap<PdfName,Object>();
    exc.put(PdfName.CONTENTS, new Integer(0x2502));
    sap.preClose(exc);
    PdfPKCS7 pk7 = new PdfPKCS7(pk, cc, null, "SHA1", "SunPKCS11-AuthProvider", false);
    MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
    byte buf[] = new byte[8192];
    int n;
    InputStream inp = sap.getRangeStream();
    while ((n = inp.read(buf)) > 0) {
        messageDigest.update(buf, 0, n);
    }
    byte hash[] = messageDigest.digest();
    byte sh[] = pk7.getAuthenticatedAttributeBytes(hash, cal, null);
    pk7.update(sh, 0, sh.length);
    PdfDictionary dic2 = new PdfDictionary();
    byte sg[] = pk7.getEncodedPKCS7(hash, cal);
    byte out[] = new byte[0x2500 / 2];
    System.arraycopy(sg, 0, out, 0, sg.length);
    dic2.put(PdfName.CONTENTS, new PdfString(out).setHexWriting(true));
    sap.close(dic2);
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11564862

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档