Java 使用iText嵌入带有pdf的SIGND数据

Java 使用iText嵌入带有pdf的SIGND数据,java,itext,digital-signature,pkcs#7,Java,Itext,Digital Signature,Pkcs#7,我有一个字符串(“>miilwwyjkozihvcnaqccoiltdccc7acaqexdzanb……”)中的编码签名数据 我需要把它和pdf结合起来签名 我正在使用以下代码 public class MyExternalSignatureContainer implements ExternalSignatureContainer { protected byte[] sig; // String b64String; public MyExternalSignatureCo

我有一个字符串(“>miilwwyjkozihvcnaqccoiltdccc7acaqexdzanb……”)中的编码签名数据

我需要把它和pdf结合起来签名

我正在使用以下代码

public class MyExternalSignatureContainer  implements ExternalSignatureContainer {
 protected byte[] sig;
 // String b64String;

    public MyExternalSignatureContainer(byte[] sig) {
    this.sig = sig;
}

@Override
public void modifySigningDictionary(PdfDictionary arg0) {
}

/**
String PKCS7Resp = "MIILwwYJKoZIhvcNAQcCoIILtDCCC7ACAQEx.........;
Base64Encoder b = new Base64Encoder();
    byte[] signedData = b.decode(PKCS7Resp.getBytes());

    PdfReader reader = new PdfReader("D:\\AADHAAR.pdf");
    FileOutputStream os = new FileOutputStream("D:\\AADHAAR1.pdf");

    ExternalSignatureContainer external = new MyExternalSignatureContainer(signedData);
    MakeSignature.signDeferred(reader, "}", os, external);

 *
 * @param arg0
 * @return
 * @throws GeneralSecurityException
 */
 @Override
public byte[] sign(java.io.InputStream in) throws GeneralSecurityException {
    throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}

public static void main(String [] args) throws DocumentException, IOException, GeneralSecurityException{
      Base64Encoder b = new Base64Encoder();
        byte[] signedData = b.decode(PKCS7Resp.getBytes());
       PdfReader reader = new PdfReader("D:\\AADHAAR.pdf");
      FileOutputStream os = new FileOutputStream("D:\\AADHAAR1.pdf");          
      ExternalSignatureContainer external = new MyExternalSignatureContainer(signedData);
         MakeSignature.signDeferred(reader, "}", os, external);
         }
          }
但这是一个明显的错误

Exception in thread "main" com.itextpdf.text.DocumentException: No field
at com.itextpdf.text.pdf.security.MakeSignature.signDeferred(MakeSignature.java:246)
at test.MyExternalSignatureContainer.main(MyExternalSignatureContainer.java:131)
  C:\Users\admin\AppData\Local\NetBeans\Cache\8.1\executor-snippets\run.xml:53: Java returned: 1
生成失败(总时间:1秒)

一致

MakeSignature.signDeferred(读取器“}”,os,外部)

参考代码

KeyStore ks = KeyStore.getInstance("pkcs12");
ks.load(new FileInputStream("my_private_key.pfx"), "my_password".toCharArray());
String alias = (String)ks.aliases().nextElement();
PrivateKey key = (PrivateKey)ks.getKey(alias, "my_password".toCharArray());
Certificate[] chain = ks.getCertificateChain(alias);
PdfReader reader = new PdfReader("original.pdf");
FileOutputStream fout = new FileOutputStream("signed.pdf");
PdfStamper stp = PdfStamper.createSignature(reader, fout, '\0');
PdfSignatureAppearance sap = stp.getSignatureAppearance();
sap.setCrypto(key, chain, null, PdfSignatureAppearance.WINCER_SIGNED);
sap.setReason("I'm the author");
sap.setLocation("Lisbon");
// comment next line to have an invisible signature
sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
sap.setExternalDigest(new byte[128], new byte[20], "RSA");
sap.preClose();
MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
byte buf[] = new byte[8192];
int n;
InputStream inp = sap.getRangeStream();
while ((n = inp.read(buf)) > 0) {
   messageDigest.update(buf, 0, n);
}
byte hash[] = messageDigest.digest();
PdfSigGenericPKCS sg = sap.getSigStandard();
PdfLiteral slit = (PdfLiteral)sg.get(PdfName.CONTENTS);
byte[] outc = new byte[(slit.getPosLength() - 2) / 2];
PdfPKCS7 sig = sg.getSigner();
Signature sign = Signature.getInstance("SHA1withRSA");
sign.initSign(key);
sign.update(hash);
sig.setExternalDigest(sign.sign(), hash, "RSA");
PdfDictionary dic = new PdfDictionary();
byte[] ssig = sig.getEncodedPKCS7();
System.arraycopy(ssig, 0, outc, 0, ssig.length);
dic.put(PdfName.CONTENTS, new PdfString(outc).setHexWriting(true));
sap.close(dic);

我做错了吗?

在第一步中,您使用自动生成的名称创建了一个签名字段:

sap.setVisibleSignature(new Rectangle(100, 100, 200, 200), 1, null);
授予相关的Javadoc:

不过,稍后,您的行为就好像签名字段名是“}”:

授予相关的Javadoc:

因此,请更改代码以使这些名称匹配,即使用您知道文档中其他表单字段不会使用的固定名称,或使用
pdfsignaturepearance
方法查询iText使用的生成名称


有人能告诉我们fieldname的值是多少吗?你说你有一个字符串中的编码签名数据,需要将它与pdf结合起来进行签名。您是否事先准备好pdf并创建了与准备好的pdf匹配的签名数据?实际上,我们正在与另一台服务器集成,该服务器请求pdf哈希和用户详细信息,并返回包含编码数据的PKCS7响应的XML。我必须使用此响应对pdf(我发送给他们的哈希)进行签名。他们说将使用iText来完成。
“}”
不可能成为
字段名。当您说我有一个字符串“MIILwwYJ…”中的编码签名数据时,您的行为就好像该数据在任何时候都与特定PDF相同。那不是真的。总会有不同的数据。我们看不到您在任何地方使用
ExternalBlankSignatureContainer
来准备PDF签名。您声称:他们说将使用iText完成,但他们是谁?他们有使用iText的商业许可证吗?如果是,请联系高级支持以获取帮助。如果他们在AGPL下使用iText,请他们发布代码。
/**
 * Sets the signature to be visible. It creates a new visible signature field.
 * @param pageRect the position and dimension of the field in the page
 * @param page the page to place the field. The fist page is 1
 * @param fieldName the field name or <CODE>null</CODE> to generate automatically a new field name
 */
public void setVisibleSignature(Rectangle pageRect, int page, String fieldName)
MakeSignature.signDeferred(reader, "}", os, external);
/**
 * Signs a PDF where space was already reserved.
 * @param reader the original PDF
 * @param fieldName the field to sign. It must be the last field
 * @param outs the output PDF
 * @param externalSignatureContainer the signature container doing the actual signing. Only the 
 * method ExternalSignatureContainer.sign is used
 * @throws DocumentException
 * @throws IOException
 * @throws GeneralSecurityException 
 */
public static void signDeferred(PdfReader reader, String fieldName, OutputStream outs, ExternalSignatureContainer externalSignatureContainer) throws DocumentException, IOException, GeneralSecurityException
/**
 * Gets the field name.
 * @return the field name
 */
public java.lang.String getFieldName()