Как подписать хеш PDF с помощью pdfbox - PullRequest
0 голосов
/ 01 октября 2018

Можно ли подписать хеш документа PDF с помощью pdfbox?Мне нужно сделать что-то вроде ниже, у меня есть Parent, который содержит PvtKey и цепочку сертификатов и дочернее приложение, которое имеет PDF-документ.Я не хочу отправлять весь поток PDF в родительское приложение, чтобы подписать его, вместо этого я буду отправлять только хэш pdf в родительское приложение (надеюсь, что родительское приложение вернет подписанный хэш).Затем подпись прикрепляется к PDF.

Я думаю, что с библиотекой IText PDF я могу сделать это.Но я хочу использовать PDFbox.

public static byte[] getCMSFromHash(byte[] hashVal,String strCertificate, String strPrivatekey){</p> <pre> byte[] cmsSignedData = null; final List<Certificate> certificates; final PrivateKey privateKey; System.out.println("Get CMS from Hash started"); Security.addProvider(new BouncyCastleProvider()); try { certificates = getFormatCertificate(strCertificate); privateKey = loadPrivateKey(strPrivatekey); @SuppressWarnings("rawtypes") Store certs = new JcaCertStore(certificates); //PAdES MessageDigest md = MessageDigest.getInstance("SHA-256"); md.update(certificates.get(certificates.size()-1).getEncoded()); byte[] certHash = md.digest(); ESSCertIDv2 essCert1 = new ESSCertIDv2(new AlgorithmIdentifier(NISTObjectIdentifiers.id_sha256), certHash); ESSCertIDv2[] essCert1Arr = { essCert1 }; SigningCertificateV2 scv2 = new SigningCertificateV2(essCert1Arr); Attribute certHAttribute = new Attribute(PKCSObjectIdentifiers.id_aa_signingCertificateV2, new DERSet(scv2)); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(certHAttribute); AttributeTable at = new AttributeTable(v); CMSAttributeTableGenerator attrGen = new DefaultSignedAttributeTableGenerator(at){ @SuppressWarnings("rawtypes") protected Hashtable createStandardAttributeTable(Map parameters) { Hashtable result = super.createStandardAttributeTable(parameters); result.remove(CMSAttributes.signingTime); return result; } }; //PAdES-end SignerInfoGeneratorBuilder genBuild = new SignerInfoGeneratorBuilder(new BcDigestCalculatorProvider()); genBuild.setSignedAttributeGenerator(attrGen); org.spongycastle.asn1.x509.Certificate certas1 = org.spongycastle.asn1.x509.Certificate.getInstance(ASN1Primitive.fromByteArray(certificates.get(certificates.size()-1).getEncoded())); ContentSigner sha1Signer = new JcaContentSignerBuilder(signerAlgorithm).build(privateKey); SignerInfoGenerator sifGen = genBuild.build(sha1Signer, new X509CertificateHolder(certas1)); CMSSignedDataGenerator gen = new CMSSignedDataGenerator(); gen.addCertificates(certs); gen.addSignerInfoGenerator(sifGen); CMSTypedData cmsdata = new CMSProcessableByteArray(hashVal); CMSSignedData signedData = gen.generate(cmsdata, false); cmsSignedData = signedData.getEncoded(); } catch (GeneralSecurityException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (OperatorCreationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (CMSException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("cmsSignedData 1::"+new String(cmsSignedData)); return cmsSignedData; }` and then `public static String getSignedPdffromCMS(byte[] cmsSignedData,String signatureName, String signatureLocation, String signatureReason){ Security.addProvider(new BouncyCastleProvider()); System.out.println("cmsSignedData 2::"+new String(cmsSignedData)); final byte[] digitalSign = cmsSignedData; Map<String, String> pdfMap = new HashMap<String, String>(); ByteArrayOutputStream pdfContentOutputStream = new ByteArrayOutputStream(); try { PDSignature signature = new PDSignature(); signature.setType(COSName.SIG); signature.setFilter(PDSignature.FILTER_ADOBE_PPKLITE); signature.setSubFilter(PDSignature.SUBFILTER_ETSI_CADES_DETACHED); if(!signatureName.isEmpty()){ signature.setName(signatureName); } if(!signatureLocation.isEmpty()){ signature.setLocation(signatureLocation); } if(!signatureReason.isEmpty()){ signature.setReason(signatureReason); } signature.setSignDate(Calendar.getInstance()); SignatureInterface signatureInterface = new SignatureInterface() { @Override public byte[] sign(InputStream content) throws IOException { return digitalSign; } }; PDDocument pdDocument = PDDocument.load(inputfile); System.out.println("PDF InputStream loaded::"); pdDocument.addSignature(signature, signatureInterface); pdDocument.saveIncremental(pdfContentOutputStream); pdDocument.close(); savePdfFile(pdfContentOutputStream); String StrPdfBase64 = ""; try { StrPdfBase64 = org.spongycastle.util.encoders.Base64.toBase64String(pdfContentOutputStream.toByteArray()); pdfMap.put("receiptContent", StrPdfBase64); System.out.println("Signed base64:::"+StrPdfBase64); } catch (Exception e) { StrPdfBase64 = "error"; System.out.println(" >>>>> pdf error occured in base64 conversion:"+e.toString()); } String receiptHash = getReceiptHash(pdfContentOutputStream); pdfMap.put("receiptHash", receiptHash); } catch (IOException e) { e.printStackTrace(); }finally { inputfile.delete(); JSONObject jsonObj = new JSONObject(pdfMap); System.out.println("pdfMap jsonObj:::"+jsonObj.toString()); return jsonObj.toString(); } }<code>

enter image description here

Созданный PDF Прикрепленный здесь

...