我正在通过HWCryto-https://github.com/open-eid/hwcrypto.js/wiki/ModernAPI-在Struts2应用程序中添加对数字签名的支持。我先创建了一个空签名,试图跟随布鲁诺·洛瓦吉的书
CertificateFactory certFactory;
try {
certFactory = CertificateFactory.getInstance("X.509");
ByteArrayInputStream in = new ByteArrayInputStream(certDecoded);
cert = (X509Certificate) certFactory.generateCertificate(in);
} catch (CertificateException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Calendar cal = Calendar.getInstance();
int estimatedSize = 8192;
PdfSignatureAppearance sap = pdfStamper.getSignatureAppearance();
sap.setVisibleSignature("sig");
sap.setCertificate(cert);
sap.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
sap.setSignDate(cal);
ExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE,
PdfName.ADBE_PKCS7_DETACHED);
try {
MakeSignature.signExternalContainer(sap, external, 8192);
pdfStamper.close();
pdfReader.close();
} catch (GeneralSecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (DocumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
之后,我得到pdf输出,并创建一个新的哈希,我将发送到智能卡
byte [] alteredPDF=output.toByteArray();
ExternalDigest externalDigest = new ExternalDigest() {
@Override
public MessageDigest getMessageDigest(String hashAlgorithm) throws GeneralSecurityException {
return DigestAlgorithms.getMessageDigest(hashAlgorithm, "BC");
}
};
PdfSignatureAppearance sapFinal = null;
try {
ByteArrayOutputStream outputFinal = new ByteArrayOutputStream();
pdfReader = new PdfReader(new ByteArrayInputStream(alteredPDF));
pdfStamper = PdfStamper.createSignature(pdfReader, outputFinal, '\0');
sapFinal = pdfStamper.getSignatureAppearance();
sapFinal.setVisibleSignature("sig");
sapFinal.setCertificationLevel(PdfSignatureAppearance.CERTIFIED_NO_CHANGES_ALLOWED);
sapFinal.setCertificate(cert);
sapFinal.setSignDate(cal);
PdfSignature dic = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
dic.setReason(sap.getReason());
dic.setLocation(sap.getLocation());
String certInfo = cert.getSubjectX500Principal().getName();
dic.setName(certInfo.substring(certInfo.indexOf("CN=") + 3,
certInfo.indexOf(",OU", certInfo.indexOf("CN=") + 3)));
dic.setSignatureCreator(sap.getSignatureCreator());
dic.setContact(sap.getContact());
dic.setCert(certDecoded);
dic.setDate(new PdfDate(sap.getSignDate()));
sapFinal.setCryptoDictionary(dic);
HashMap<PdfName, Integer> exc = new HashMap<PdfName, Integer>();
exc.put(PdfName.CONTENTS, new Integer(estimatedSize * 2 + 2));
sapFinal.preClose(exc);
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
byte[] sh = null;
byte[] hashVal = null;
PdfPKCS7 sgn = null;
try {
sgn = new PdfPKCS7(null, new Certificate[] { cert }, "SHA256", null, externalDigest, false);
InputStream data = sapFinal.getRangeStream();
hashVal = DigestAlgorithms.digest(data, externalDigest.getMessageDigest("SHA256"));
sh = sgn.getAuthenticatedAttributeBytes(hashVal, cal, null, null, CryptoStandard.CMS);
sh = MessageDigest.getInstance("SHA256", "BC").digest(sh);
} catch (IOException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchProviderException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (GeneralSecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
最后得到了生成的签名
sgn.setExternalDigest(sig, null, "RSA");
byte[] encodedSign = null;
try {
System.out.println(Arrays.toString(Hex.decodeHex(hash.toCharArray())));
encodedSign = sgn.getEncodedPKCS7(Hex.decodeHex(hash.toCharArray()), cal, null, null, null,
CryptoStandard.CMS);
} catch (DecoderException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
MakeSignature.signDeferred(pdfReader, "sig", output,
new MyExternalSignatureContainer(encodedSign));
} catch (DocumentException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (GeneralSecurityException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("called sign pdf");
try {
FileOutputStream outputStream = new FileOutputStream("d:\\debug.pdf");
output.writeTo(outputStream);
output.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
谁能告诉我我做错了什么?
终于解决了我的问题。将空签名存储到PDF中并重新创建输出流是罪魁祸首。设法从头到尾使用相同的outputstream,效果很好。此链接-https://github.com/sueastside/BEIDSign/blob/master/beidsign-service/src/main/java/be/redtree/beid/services/SignatureServiceImpl.java-当然帮了我。感谢mkl抽出时间。
我已经研究了所有类似的问题,但找不到一个应用itextsharp延迟签名的案例。 基本上,我的应用程序使用签名对pdf文档进行签名,该签名是由远程web服务创建的。 我的应用程序向这个web服务发送原始文档的哈希(添加空签名字段后可签名字节的哈希),并接收一个Base64编码的签名文件。 我将此签名嵌入到先前生成的临时pdf文件中,该文件具有空签名字段。 最后,我的签名未被验证,因为Adobe R
我正在使用PDFbox-1.8.8在PDF文件上做签名功能。 当我签署一份文件的时候 下面是我的代码:
我检查了Stackoverflow上的其他类似问题,但它在我的案例中不起作用。 情境:我正在开发一个需要签署pdf文档的应用程序。签名密钥由另一家公司持有,假设它是Companya。 我做了以下几个步骤: null 然后,将消息摘要发送给CompanyA进行签名。在我从CompanyA获得签名的摘要(它是base64编码的)之后,我调用方法来获得签名的pdf文档。 最后我可以得到签名的pdf文档,
对于一个关于签名数据被哈希两次的C#问题,我看到了一个类似的答复,但是我不知道为什么我的签名数据会出现在这里。 C#PKCS7 Smartchard数字签名损坏
我正在为我的应用程序做一个PDF签名功能。以下是工作流程: PDF存储在服务器上。 我将所有必需的签名字段包含到文件中,并使用ZendPDF的扩展名为FaritPDF计算字节长度等。 我根据使用SHA256计算的字节长度计算哈希。 哈希将发送到客户端。 客户端使用PFX文件对哈希进行签名,并创建包含哈希的PKCS7对象。 将PKCS7对象发送到服务器。 PKCS7对象包含在PDF中,并呈现PDF。