Я использую iText 5.5.5 для Java, и я хотел бы создать подписанный PDF с внешней подписью следующим образом:
Возьмите документ PDF, который должен быть подписан и создать PDF с пустой подписью и предоставить байты с кодировкой BASE64, которые должны быть подписаны внешним механизмом подписи:
PdfReader reader = new PdfReader(src);
FileOutputStream os = new FileOutputStream(dest);
PdfStamper stamper = PdfStamper.createSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.getSignatureAppearance();
appearance.setVisibleSignature(new Rectangle(36, 748, 144, 780), 1, "test");
appearance.setCertificate(chain[1]);
ExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
MakeSignature.signExternalContainer(appearance, external, 8192);
InputStream is = appearance.getRangeStream();
byte[] toSign = getBytes(is);
this.b64String = new String(Base64.encode(toSign));
Знак b64String
с механизмом внешней подписи, обеспечивающим подпись в качестве PKCS # 7 подписанных данных в BASE64.
Создайте ExternalSignatureContainer
чтобы иметь только подписанные данные PKCS # 7 из внешнего механизма подписи:
public class MyExternalSignatureContainer implements ExternalSignatureContainer {
protected byte[] sig;
public MyExternalSignatureContainer(byte[] sig) {
this.sig = sig;
}
@Override
public void modifySigningDictionary(PdfDictionary arg0) {
}
@Override
public byte[] sign(InputStream arg0) throws GeneralSecurityException {
return sig;
}
}
Создать подписанный документ PDF с помощью MyExternalSignatureContainer:
PdfReader reader = new PdfReader(dest);
FileOutputStream os = new FileOutputStream(signedpdf);
ExternalSignatureContainer external = new MyExternalSignatureContainer(signedData);
MakeSignature.signDeferred(reader, "test", os, external);
Но я попадаю на последнюю строку MakeSignature.signDeferred(reader, "test", os, external);
следующее исключение:
com.itextpdf.text.DocumentException: Not enough space
Где проблема и как ее решить?
Вы сделали оценку того, что подпись будет вписываться в 8192 байта. Однако количество байтов байта подписи byte[]
превышает 8192, поэтому исключение Недостаточно места. Например: ваш внешний контейнер подписи возвращает подпись, которая измеряет 10000 байт. iText сообщает вам, что 10000 больше, чем 8192, и что вы спрашиваете то, что невозможно.
Как исправить это: сделайте более точную оценку при создании PDF с пустой подписью.
MakeSignature.signExternalContainer(appearance, external, 55000);
, Тогда нет никаких исключений, но файл, сохраненный в расположении signedpdf
имеет 0 байтов. Что случилось?
Скажите вашему контейнеру, что размер оценивается:
MakeSignature.signExternalContainer(appearance, external, 0);
Согласно API MakeSignature
measuredSize - зарезервированный размер для подписи. Это будет оценено, если 0