package br.com.valid.cd.vsigner.demo; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.List; import java.util.UUID; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfStamper; import com.itextpdf.text.pdf.codec.Base64; import com.itextpdf.text.pdf.security.MakeSignature; import com.itextpdf.text.pdf.security.MakeSignature.CryptoStandard; import br.com.valid.cd.vsigner.demo.contants.PropertiesFile; import br.com.valid.cd.vsigner.demo.utils.Crypt; import br.com.valid.cd.vsigner.demo.utils.PDFFile; import br.com.valid.cd.vsigner.demo.utils.RequestSession; import br.com.valid.cd.vsigner.demo.ws.cxf.signer.BillingInfoReq; import br.com.valid.cd.vsigner.demo.ws.cxf.signer.CmsPackageType; import br.com.valid.cd.vsigner.demo.ws.cxf.signer.ServiceError; import br.com.valid.cd.vsigner.demo.ws.cxf.signer.SignerParameters; import br.com.valid.cd.vsigner.demo.ws.cxf.signer.SignerResult; /** *
* Invoca o serviço de assinatura digital de documentos - Preparação do pacote que será assinado. * Nesse exemplo é utilizada a política AD-RB e o documento é um PDF * */ public class PDFPrepareToSignService extends HttpServlet { private static final long serialVersionUID = 6453542378086966289L; public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String errors = ""; FileInputStream pdfInputStream = null; try { // Configura canal SSL Crypt.configureSSLChannel(); // Recupera o certificado selecionado pelo cliente utilizando o websocket String signerCertificate = req.getParameter("certificateSelected"); // Recupera o thumbprint do certificado selecionado pelo cliente utilizando o websocket String signerCertificateThumbPrint = req.getParameter("thumbprint"); boolean timeStampSignature = Boolean.parseBoolean(PropertiesFile.getKeyValue(PropertiesFile.VSIGNER_SIGN_TIMESTAMP)); // Transforma o certificado no formato PEM em um X509Certificate X509Certificate x509SignerCertificate = Crypt.getX509SignerCertificate(signerCertificate); HttpSession session = req.getSession(); //A partir daqui realiza a leitura do diretório com os arquivos a ser File dir = new File(PropertiesFile.getKeyValue(PropertiesFile.PDF_DIR_TO_SIGN_KEY)); File[] archives = dir.listFiles(); Listlist = new ArrayList (); for(File f : archives) { // Gera um UUID para o PDF String uuid = UUID.randomUUID().toString(); pdfInputStream = PDFFile.getMultiplePdfInputStream(f); PdfReader pdfReader = new PdfReader(PDFFile.getPdfContent(pdfInputStream, 64*1024)); // Cria um selo (não visível) de assinatura digital ByteArrayOutputStream osPDF = new ByteArrayOutputStream(); //PdfStamper stamper = PdfStamper.createSignature(pdfReader, osPDF, '\0'); PdfStamper stamper = PdfStamper.createSignature(pdfReader, osPDF, '\000', null, true); stamper.getSignatureAppearance().setVisibleSignature(new Rectangle(0,0,0,0),1,uuid); // Recupera buffer que deverá ser assinado byte[] dataToBeSignedOut = MakeSignature.getDataTobeSigned(stamper.getSignatureAppearance(), (int) (PDFFile.getPdfLength() * 2), CryptoStandard.CMS, x509SignerCertificate); // Calcula o hash sobre o buffer a ser assinado (usando SHA-256) byte[] hash = Crypt.calcHash(dataToBeSignedOut); // Configura informações para bilhetagem BillingInfoReq billingInfoReq = new BillingInfoReq(); if(timeStampSignature) { billingInfoReq.setContractUuid(PropertiesFile.getKeyValue(PropertiesFile.CONTRACT_SIGN_RT_UUID_KEY)); } else { billingInfoReq.setContractUuid(PropertiesFile.getKeyValue(PropertiesFile.CONTRACT_SIGN_RB_UUID_KEY)); } // Código de identificação do cliente billingInfoReq.setUserCode(PropertiesFile.getKeyValue(PropertiesFile.USER_CODE_KEY)); // Parametros para preparação do pacote que será assinado SignerParameters signerParameters = new SignerParameters(); // Bilhetagem signerParameters.setBillingInfoReq(billingInfoReq); if(timeStampSignature) { // Tipo da política (AD-RT) signerParameters.setCmsPackageType(CmsPackageType.P_AD_ES_AD_RT); } else { // Tipo da política (AD-RB) signerParameters.setCmsPackageType(CmsPackageType.P_AD_ES_AD_RB); } // Valor do hash do dado a ser assinado signerParameters.setHashData(hash); // Algoritmo de hash utilizado signerParameters.setMdAlg("SHA-256"); // Data vazio (PDF sempre é no formato detached) signerParameters.setData(new byte[0]); // Certificado digital do assinante signerParameters.setX509SigningCertificate(x509SignerCertificate.getEncoded()); SignerResult sr = Crypt.getExternalSignerWS().externalPreSignCMS(signerParameters); String signaturePackageResult = null; if(sr.getSignaturePackage()!= null) { signaturePackageResult = Base64.encodeBytes(sr.getSignaturePackage()); } //insere os dados de todos os arquivos em uma lista list.add(new RequestSession(uuid, signaturePackageResult, osPDF, hash,sr,f.getName())); } List errorsList = new ArrayList<>(); //iteração para verificar se obteve sucesso em todos os arquivos for(RequestSession reqSession : list) { // Verifica status de retorno if(!reqSession.getSignerResult().isSuccess()) { errorsList.add((ServiceError) reqSession.getSignerResult().getErrorList()); if (errorsList != null) { for (ServiceError serviceError : errorsList) { errors += serviceError.getErrorCode() + ": " + serviceError.getErrorMessage() + "\n"; } res.getWriter().println(errors); } System.out.println(errors); } } //se nao possuir erros nos dados da lista if(errorsList.isEmpty()) { session.setAttribute("certificateSelected", signerCertificate); session.setAttribute("thumbprint", signerCertificateThumbPrint); session.setAttribute("signatureAlg", "SHA256WithRSA"); session.setAttribute("listRequestSession", list); session.setAttribute("length", list.size()); res.sendRedirect("pdfSignerStep2.jsp"); } } catch (Exception e) { e.printStackTrace(); } } }