Assinatura digital PKCS11

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;
}


}

pelo jeito esse esse .close(), onde da o erro, era para estar sendo feito no objeto appearance. veja o que a api diz:

If closing a signed document with an external signature the closing must be done in the PdfSignatureAppearance instance.

e outra, coloque seu código dentro da tag code, pq facilita na hora de tentar te ajudar :wink:

ae galera consegui assinar o arquivo digitalmente o codigo ficou assim para quem se interessar ou precisar:

import java.applet.Applet;
import java.awt.*;

import javax.swing.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

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.PdfReader;   
import com.itextpdf.text.pdf.PdfSignatureAppearance;   
import com.itextpdf.text.pdf.PdfStamper;   

import java.security.*;
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(); 
		} catch (GeneralSecurityException e) {
			e.printStackTrace();
		} 	
}

public static void signFile(String filenameforsign, String reason, String location, String contact, PrivateKey key, Certificate[] chain) throws SignatureException { 
	PdfReader reader;

	try {
	
		reader = new PdfReader(filenameforsign);
		String arquivoAssinado = filenameforsign.substring(0, filenameforsign.lastIndexOf(".")) + "_signed.pdf";
		FileOutputStream fout = new FileOutputStream(arquivoAssinado);
		PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0');
		PdfSignatureAppearance sap = stp.getSignatureAppearance();
		sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
		sap.setReason("Eu sou o autor");
		sap.setLocation("AGU");
		// comente a linha abaixo caso queira uma assinatura invisivel
		sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
		stp.close();

		
	} catch (IOException ex) { 
		ex.printStackTrace(); 
		System.out.println("Erro de IO");
	} catch (DocumentException e) { 
		e.printStackTrace(); 
		System.out.println("Erro de Documento");
	} 
} 

}

no appletViewr esta funcionando certinho ai fiz o HTML da applet,
só que estou com um probleminha no HTML agora:


<HTML>
<HEAD>
<TITLE> Assina PDF </TITLE>
</HEAD>
<BODY>
<APPLET CODE=AbrePdf.class codebase="" archive="AbrePdf.jar"  WIDTH=500 HEIGHT=500>
</APPLET>
</BODY>
</HTML>

a console esta retornando o erro:

java.lang.reflect.InvocationTargetException
at com.sun.deploy.util.DeployAWTUtil.invokeAndWait(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.runOnEDT(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.createApplet(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.sun.security.pkcs11)
at java.security.AccessControlContext.checkPermission(Unknown Source)
at java.security.AccessController.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPermission(Unknown Source)
at java.lang.SecurityManager.checkPackageAccess(Unknown Source)
at sun.plugin2.applet.Applet2SecurityManager.checkPackageAccess(Unknown Source)
at java.lang.ClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.lang.ClassLoader.checkPackageAccess(Unknown Source)
at java.lang.Class.getDeclaredConstructors0(Native Method)
at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
at java.lang.Class.getConstructor0(Unknown Source)
at java.lang.Class.newInstance0(Unknown Source)
at java.lang.Class.newInstance(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$12.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Exception: java.lang.reflect.InvocationTargetException
java.lang.NullPointerException
at sun.plugin2.applet.Plugin2Manager.findAppletJDKLevel(Unknown Source)
at sun.plugin2.applet.Plugin2Manager.createApplet(Unknown Source)
at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Exception: java.lang.NullPointerException

Alguém da uma luz?

[quote=jailson.dossantos]
Alguém da uma luz?[/quote]

a applet precisa estar assinada para poder acessar arquivos em disco:

http://www.guj.com.br/posts/list/38124.java

Legal assinei o jar do projeto da applet e começou a dar erro com a biblioteca do iText, dai peguei o jar da biblioteca do iText assinei a mesma e no meu projeto referencie a jar assinada, gerei novo jar do projeto e assinei o jar novamente, so que ta me retornando o erro:

java.lang.NoClassDefFoundError: com/itextpdf/text/DocumentException
	at java.lang.Class.getDeclaredConstructors0(Native Method)
	at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
	at java.lang.Class.getConstructor0(Unknown Source)
	at java.lang.Class.newInstance0(Unknown Source)
	at java.lang.Class.newInstance(Unknown Source)
	at sun.applet.AppletPanel.createApplet(Unknown Source)
	at sun.plugin.AppletViewer.createApplet(Unknown Source)
	at sun.applet.AppletPanel.runLoader(Unknown Source)
	at sun.applet.AppletPanel.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.itextpdf.text.DocumentException
	at sun.applet.AppletClassLoader.findClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at sun.applet.AppletClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClass(Unknown Source)
	at java.lang.ClassLoader.loadClassInternal(Unknown Source)
	... 10 more

Não entende porque esta dando esse erro visto que no applet view a applet roda certinho. Se puder me ajudar, agradeço desde ja.