Boa tarde pessoal, estou fazendo uma applet para assinar digitalmente um arquivo pdf.
Minha assinatura esta em um token da pronova e2000. Escrevi o codigo abaixo, porém quando rodo a applet o arquivo parece que é assinado mas na hora de abrir o arquivo da mensagem que o arquivo esta corrompido e na console java aparece o seguinte erro:
java.security.ProviderException: sun.security.pkcs11.wrapper.PKCS11Exception: CKR_GENERAL_ERROR
Se alguém puder me ajudar em dizer o que esta errado, ja procurei bastante na internet sobre esse erro, mas não ficou claro o problema visto que a classe PKCS11 ja esta incluida na biblioteca do projeto. Percebi tb que o erro acontece na linha de código: stamper.close();
import java.awt.*;
import javax.swing.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.applet.Applet;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfPKCS7;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
import java.security.*;
import java.security.cert.CertStoreException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import sun.security.pkcs11.*;
public class AbrePdf extends Applet {
Button botão;
Button abrir;
TextField arquivo = new TextField("PDF", 20);
String path = "";
char[] password;
public void init() {
botão = new Button("Selecionar arquivo");
abrir = new Button("Assinar");
arquivo.setEditable(false);
add(arquivo);
add(botão);
add(abrir);
abrir.setEnabled(false);
}
public boolean action (Event evt, Object algum) {
if (evt.target == botão) {
path = loadFile(new Frame(), "Selecionar PDF",".\\" ,"*.PDF");
arquivo.setText(path);
abrir.setEnabled(true);
return true;
}
else{
if (evt.target == abrir){
try {
abrePDF();
} catch (SignatureException e) {
e.printStackTrace();
}
return true;
}else
return false;
}
}
public String loadFile(Frame f, String title, String defDir, String fileType) {
JFileChooser fc = new JFileChooser ();
fc.showOpenDialog(null);
File file = fc.getSelectedFile();
return file.getPath();
}
public void abrePDF() throws SignatureException {
password = getPIN("Digite sua senha");
configuraProvider();
}
public char[] getPIN(String prompt) {
final JPasswordField jpf = new JPasswordField();
JComponent[] components = new JComponent[2];
components[0] = new JLabel(prompt);
components[1] = jpf;
JOptionPane jop = new JOptionPane(components, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
JDialog dialog = jop.createDialog("Digite o PIN");
dialog.addComponentListener(new ComponentAdapter(){
public void componentShown(ComponentEvent e){
jpf.requestFocusInWindow();
}
});
dialog.setVisible(true);
char[] ret = jpf.getPassword();
dialog.dispose();
return ret;
}
public void configuraProvider() throws SignatureException{
PrivateKey key = null;
java.security.cert.Certificate[] chain = null; //carrega o certificado do smartcard
try {
//caminho para o arquivo de configuração(smart_pkcs11.cfg)
String config = "D:\\desenvolvimento\\eclipse3.5\\workspace\\AbrePdf\\smart_pkcs11.cfg";
Provider pkcs11Provider = new SunPKCS11(config);
Security.addProvider(pkcs11Provider);
KeyStore ks = KeyStore.getInstance("PKCS11");
ks.load(null, password);
String alias = (String)ks.aliases().nextElement();
key = (PrivateKey)ks.getKey(alias,password);
chain = ks.getCertificateChain(alias);
signFile(path, "Eu sou o autor", "Brasilia", "AGU", key, chain);
} catch (KeyStoreException e) {
System.out.println("Erro no Keystore.");
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
System.out.println("Erro no algoritmo.");
e.printStackTrace();
}catch (CertificateException e) {
System.out.println("Erro no certificado.");
e.printStackTrace();
} catch (FileNotFoundException e) {
System.out.println("Arquivo não encontrado.");
e.printStackTrace();
} catch (IOException e) {
System.out.println("Erro no arquivo.");
e.printStackTrace();
} catch (UnrecoverableKeyException e) {
System.out.println("Não foi possivel recuperar a chave.");
e.printStackTrace();
}
}
public static void signFile(String filenameforsign, String reason, String location, String contact, PrivateKey key, Certificate[] chain) throws SignatureException {
PdfReader reader;
PdfStamper stamper;
PdfSignatureAppearance appearance;
FileOutputStream os;
try {
reader = new PdfReader(filenameforsign);
String arquivoAssinado = filenameforsign.substring(0, filenameforsign.lastIndexOf(".")) + "_signed.pdf";
os = new FileOutputStream(arquivoAssinado);
stamper = PdfStamper.createSignature(reader, os, '\0', null, true);
appearance = stamper.getSignatureAppearance();
appearance.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
appearance.setCrypto(key, chain, null,PdfSignatureAppearance.SELF_SIGNED);
appearance.setReason(reason);
appearance.setLocation(location);
appearance.setContact(contact);
stamper.close();
verifySignature(arquivoAssinado);
} catch (IOException ex) {
ex.printStackTrace();
System.out.println("Erro de IO");
} catch (DocumentException e) {
e.printStackTrace();
System.out.println("Erro de Documento");
}
}
public static boolean verifySignature(String arquivoAssinado) throws SignatureException {
boolean ret = false;
try{
PdfReader reader = new PdfReader(arquivoAssinado);
AcroFields af = reader.getAcroFields();
PdfPKCS7 pk = af.verifySignature(arquivoAssinado);
ret = pk.verify();
}catch (IOException e) {
e.printStackTrace();
}
System.out.println(ret);
return ret;
}
}