2014-02-24 90 views
1

我嘗試使用iText爲JAVA和葡萄牙公民卡(智能卡)在pdf中創建簽名。但是,當代碼執行MakeSignature類我總是收到一個錯誤說:iText和數字簽名

java.security.InvalidKeyException:提供的密鑰(sun.security.pkcs11.P11Key $ P11PrivateKey)不是一個RSAPrivateKey實例

我需要一些幫助,任何人都可以幫助我嗎?

try { 
     String pkcs11Config = "name=GemPC" + "\n" + "library=C:/WINDOWS/system32/pteidpkcs11.dll"; 
     ByteArrayInputStream configStream = new ByteArrayInputStream(pkcs11Config.getBytes()); 
     Provider pkcs11Provider = new sun.security.pkcs11.SunPKCS11(configStream); 

     Security.addProvider(pkcs11Provider); 
     CallbackHandler cmdLineHdlr = new DialogCallbackHandler(); 

     KeyStore.Builder builder = KeyStore.Builder.newInstance("PKCS11", pkcs11Provider, 
       new KeyStore.CallbackHandlerProtection(cmdLineHdlr)); 

     KeyStore ks = builder.getKeyStore(); 

     PdfReader pdf = new PdfReader(filePath); 
     FileOutputStream fos = new FileOutputStream(dest); 
     PdfStamper stp = PdfStamper.createSignature(pdf, fos, '\0'); 
     PdfSignatureAppearance sap = stp.getSignatureAppearance(); 
     sap.setReason("I'm the author"); 

     String alias = (String) ks.aliases().nextElement(); 

     PrivateKey pk = (PrivateKey) ks.getKey("CITIZEN SIGNATURE CERTIFICATE", null); 
     Certificate chain = ks.getCertificate(alias); 

     X509Certificate x509 = (X509Certificate) chain; 
     x509.checkValidity(); 

     ExternalSignature es = new PrivateKeySignature(pk, "SHA-1", "BC"); 
     ExternalDigest digest = new BouncyCastleDigest(); 
     Certificate[] certs = new Certificate[1]; 
     certs[0] = chain; 

     MakeSignature.signDetached(sap, digest, es, certs, null, null, null, 0, CryptoStandard.CMS); 
     return dest; 
    } catch (CertificateExpiredException | CertificateNotYetValidException ex) { 
     Logger.getLogger(Signer.class.getName()).log(Level.SEVERE, null, ex); 
     return null; 
    } 
+0

所有的樣品我看到了實現此功能使用的葡萄牙公民卡用空密碼製成。而這個工作與iText 5.2,但不能在iText5.5工作,因爲API的變化。我使用SHA1哈希算法進行測試,因爲所有樣本都使用它。 – pedrofernandes

+0

你是對的,我回答得太快了。密碼是在PKCS#11的稍後階段輸入的。 –

+0

SHA1是葡萄牙公民卡的標準。它使用SHA1 RSA加密。我確認過了。 – pedrofernandes

回答

4

如果你有一個智能卡(PKCS11)你的私鑰,因爲您的主要材料是安全設備不能wrapp在java.security.interfaces.RSAPrivateKey這個關鍵。

那麼可能就必須更改供應商在你的代碼:

ExternalSignature es = new PrivateKeySignature(pk, "SHA-1", "BC"); 

爲:

ExternalSignature es = new PrivateKeySignature(pk, "SHA-1", pkcs11Provider.getName()); 

希望這有助於

+0

是它的作品,但是簽名不認證,也許有同樣的錯誤認爲。 – pedrofernandes

+0

我不明白你的評論,當你說「簽名沒有被認證」時,你是什麼意思? – albciff

+0

對不起。 Acrobat說我的簽名無法驗證。 – pedrofernandes