Рассчитайте хэш SHA-256 полного подготовленного PDF-файла и отправьте его в Swisscom. < /p>
[*]. SignatureObject.cms Из Swisscom я снова открыл подготовленный PDF, снова проверил хэш и попытался внедрить подпись, используя SignDeferred.import com.itextpdf.io.image.ImageData;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.layout.Canvas;
import com.itextpdf.layout.element.Image;
import com.itextpdf.signatures.*;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.*;
import java.security.MessageDigest;
import java.security.Security;
import java.util.*;
public class PrepareHash {
public static void main(String[] args) {
if (args.length < 3) {
System.err.println("Usage: java PrepareHash ...");
return;
}
String inputPDF = args[0];
String outputPDF = args[1];
String[] signatureImagePaths = Arrays.copyOfRange(args, 2, args.length);
try {
Security.addProvider(new BouncyCastleProvider());
// Add visual overlays
ByteArrayOutputStream visualized = new ByteArrayOutputStream();
PdfDocument pdfDoc = new PdfDocument(new PdfReader(inputPDF), new PdfWriter(visualized));
for (int i = 0; i < signatureImagePaths.length; i++) {
ImageData imageData = ImageDataFactory.create(signatureImagePaths);
Image image = new Image(imageData);
Rectangle pageSize = pdfDoc.getPage(i + 1).getPageSize();
image.setFixedPosition(i + 1, 0, 0);
image.setWidth(pageSize.getWidth());
image.setHeight(pageSize.getHeight());
new Canvas(pdfDoc.getPage(i + 1), pageSize).add(image);
}
pdfDoc.close();
// Hash and prepare the signed placeholder PDF
ByteArrayInputStream hashInput = new ByteArrayInputStream(visualized.toByteArray());
FileOutputStream signedOut = new FileOutputStream(outputPDF);
PdfSigner signer = new PdfSigner(new PdfReader(hashInput), signedOut, new StampingProperties().useAppendMode());
signer.setFieldName("Signature1");
MessageDigest digest = MessageDigest.getInstance("SHA-256");
IExternalSignatureContainer dummyContainer = new IExternalSignatureContainer() {
@Override
public byte[] sign(InputStream is) {
try {
byte[] buffer = new byte[8192];
int read;
while ((read = is.read(buffer)) != -1) {
digest.update(buffer, 0, read);
}
byte[] hash = digest.digest();
String base64Hash = Base64.getEncoder().encodeToString(hash);
System.out.println("
return new byte[0];
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void modifySigningDictionary(PdfDictionary dic) {
dic.put(PdfName.Filter, PdfName.Adobe_PPKLite);
dic.put(PdfName.SubFilter, PdfName.ETSI_CAdES_DETACHED);
dic.put(PdfName.M, new PdfString(new PdfDate().toString()));
dic.put(PdfName.Reason, new PdfString("Visual signature + Hash"));
dic.put(PdfName.Location, new PdfString("DS | SIGN"));
}
};
signer.signExternalContainer(dummyContainer, 25000);
System.out.println("
} catch (Exception e) {
System.err.println("
e.printStackTrace();
}
}
}
< /code>
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.signatures.*;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Security;
public class SignQES {
public static void main(String[] args) {
if (args.length < 4) {
System.err.println("Usage: java SignQES ");
System.exit(1);
}
String inputPdf = args[0];
String outputPdf = args[1];
String signatureCmsPath = args[2];
String reason = args[3];
try {
Security.addProvider(new BouncyCastleProvider());
byte[] signatureBytes = Files.readAllBytes(Paths.get(signatureCmsPath));
PdfReader reader = new PdfReader(inputPdf);
PdfSigner signer = new PdfSigner(reader, new FileOutputStream(outputPdf), new StampingProperties().useAppendMode());
IExternalSignatureContainer container = new IExternalSignatureContainer() {
@Override
public byte[] sign(InputStream data) {
return signatureBytes;
}
@Override
public void modifySigningDictionary(PdfDictionary dic) {
dic.put(PdfName.Filter, PdfName.Adobe_PPKLite);
dic.put(PdfName.SubFilter, PdfName.ETSI_CAdES_DETACHED);
}
};
signer.signDeferred(signer.getDocument(), "Signature1", new FileOutputStream(outputPdf), container);
System.out.println("QES Signature applied to: " + outputPdf);
} catch (Exception e) {
System.err.println("Signing error: " + e.getMessage());
e.printStackTrace();
System.exit(2);
}
}
}
< /code>
update3.0
Я использую ITEXT 7 (V7.2.5, версия AGPL) и BouncyCastle (v1.74) для реализации квалифицированных электронных подписей (QE) в Java. Я генерирую хэш подписи, используя Signdeferred (), а затем получаю подпись CMS от внешнего поставщика доверительных услуг (Swisscom), которую я затем внедряю с помощью SignexternalContainer. Поскольку я вручную собираю структуру CMS через BouncyCastle перед ее внедрением, мне интересно: < /p>
Как я могу добавить атрибут времени подписания вручную при использовании метода Signdeferred ()? v1.74)? < /p>
Можно ли это сделать до встроения в SignexternalContainer ()? /> < /li>
swisscom qes api (формат etsi)
Все остальное зеленое и действительное.>
Подробнее здесь: https://stackoverflow.com/questions/795 ... smatch-exp