Можно ли подписать хеш документа 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>
Созданный PDF Прикрепленный здесь