是否可以使用pdfbox签名PDF文档哈希? 我需要做下面的事情, 我有一个包含PvtKey和证书链的父项,以及一个具有PDF文档的子应用程序。我不想将整个pdf流发送到父应用程序进行签名,而是只将pdf哈希发送到父应用程序(希望父应用程序将返回Signed哈希值)。然后将签名附加到pdf。
我认为使用IText pdf库可以做到这一点。但是我想使用PDFbox。
public static byte[] getCMSFromHash(byte[] hashVal,String strCertificate, String strPrivatekey){
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>