Boa Tarde Pessoal, td bom ?
Estou precisando fazer uma rotina para listar todos os certificados digitais instalados no pc para poder utiliza-los para assinar digitalmente Arquivos PDF.
Achei a API da Chikat http://www.chilkatsoft.com/ que utiliza uma .dll para ler os certificados.
Essa api até que lista todos os certificados digitais porem ela não me fornece uma interface para poder pegar o certificado e utiliza-lo.
Segue abaixo uma simples classe que cria um PDF hello world e em seguida cria uma cópia assinada digitalmente
pela certificação luke.pfx até ai tudo bem o pfd é assinado digitalmente.
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.*;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfSignatureAppearance;
import com.itextpdf.text.pdf.PdfStamper;
import com.itextpdf.text.pdf.PdfWriter;
public class AssinaPDF {
/**
* Documento a ser criado
*/
static String fname = "C:\\HelloWorld.pdf" ;
/**
* Documento Assinado
*/
static String fnameS = "C:\\HelloWorld_sign.pdf" ;
public static void main(String[] args) {
try {
AssinaPDF sign_pdf = new AssinaPDF();
sign_pdf.buildPDF() ;
sign_pdf.signPdf() ;
}
catch(Exception e) { }
}
/**
* Cria um simples PDF "Hello World"
*/
public static void buildPDF() {
// Creation du document
Document document = new Document();
try {
// Creation du "writer" vers le doc
// directement vers un fichier
PdfWriter.getInstance(document,
new FileOutputStream(fname));
// Ouverture du document
document.open();
// Ecriture des datas
document.add(new Paragraph("Hello World"));
} catch (DocumentException de) {
System.err.println(de.getMessage());
} catch (IOException ioe) {
System.err.println(ioe.getMessage());
}
// Fermeture du document
document.close();
}
/**
* Assina o PDF
*/
public static final boolean signPdf()
throws IOException, DocumentException, Exception
{
//caminho da certificação
String fileKey = "C:\\luke.pfx" ;
//senha da certificação
String fileKeyPassword = "serasa";
try {
KeyStore ks = KeyStore.getInstance("pkcs12");
ks.load(new FileInputStream(fileKey), fileKeyPassword.toCharArray());
String alias = (String)ks.aliases().nextElement();
// Recupera a chave privada
PrivateKey key = (PrivateKey)ks.getKey(alias, fileKeyPassword.toCharArray());
System.out.println("algoritmo ="+key.getEncoded());
// pega o certificado
Certificate[] chain = ks.getCertificateChain(alias);
for(int i=0; i< chain.length-1;i++){
System.out.print(chain[i]);
}
// Le o Documento Fonte
PdfReader pdfReader = new PdfReader((new File(fname)).getAbsolutePath());
File outputFile = new File(fnameS);
// Criação do selo de assinatura
PdfStamper pdfStamper;
pdfStamper = PdfStamper.createSignature(pdfReader, null, '\0', outputFile);
PdfSignatureAppearance sap = pdfStamper.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);
pdfStamper.close(); ;
return true;
}
catch (Exception key) {
throw new Exception(key);
}
}
}
Aqui segue a classe que utiliza a lib Chilkat para listar todas as certificações do usuario na maquina.
import com.chilkatsoft.CkCert;
import com.chilkatsoft.CkCertStore;
import com.chilkatsoft.CkCreateCS;
public class ChilkatExample {
static {
try {
//carrega a dll chikat.dll
System.loadLibrary("chilkat");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load.\n" + e);
System.exit(1);
}
}
public static void main(String argv[])
{
CkCreateCS ccs = new CkCreateCS();
ccs.put_ReadOnly(true);
CkCertStore cs;
//pega os certificados do usuário na máquina
cs = ccs.OpenCurrentUserStore();
if (!(cs == null )) {
CkCert cert;
int numCerts;
numCerts = cs.get_NumCertificates();
int i;
// Printa o nome de cada certificado
for (i = 0; i <= numCerts - 1; i++) {
cert = cs.GetCertificate(i);
System.out.println(cert.subjectDN());
}
}
else {
System.out.println(ccs.lastErrorText());
}
}
}
Fiquei caçando no google por um bom tempo para conseguir algo, e só achei o chikat e ele não me da alguma interface para eu pegar os objetos PrivateKey na linha 94 e o array de bytes do objeto na linha 99 do primeiro código. Assim não consigo assinar o pdf.
Alguem pode me dar um help ?
Valeu