Hash -Nichtübereinstimmung vor QES unterschreibt sich bei Swisscom und Itext 7 - "Hash -Nichtübereinstimmung! Erwartet .Java

Java-Forum
Anonymous
 Hash -Nichtübereinstimmung vor QES unterschreibt sich bei Swisscom und Itext 7 - "Hash -Nichtübereinstimmung! Erwartet .

Post by Anonymous »

Ich implementiere einen qualifizierten elektronischen Signature (QES) -Flow unter Verwendung von Swisscom Trust Services und IText 7.2.5 in Java. Ich stecke an dem Schritt fest, in dem ich den während der Vorbereitung erzeugten SHA-256-Hash mit dem erwarteten Hash (zur Erzeugung der Signatur über Swisscom) vergleiche. Die Hashes stimmen nicht überein, und daher fällt die Signierung aus. /> Speichern Sie die resultierenden _prepared.pdf < /code>. SignatureObject.cms Von Swisscom habe ich den vorbereiteten PDF erneut geöffnet, den Hash erneut verifiziert und versucht, die Signatur mit Signdeferred einzubetten.import com.itextpdf.kernel.geom.Rectangle;
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.signatures.ExternalBlankSignatureContainer;
import com.itextpdf.signatures.IExternalSignatureContainer;
import com.itextpdf.signatures.PdfSigner;

import java.io.*;
import java.security.MessageDigest;
import java.util.Base64;

public class PrepareHash {
public static void main(String[] args) throws Exception {
if (args.length != 3) {
System.err.println("Usage: java PrepareHash input.pdf output_hash.txt output_prepared.pdf");
System.exit(1);
}

String inputPdf = args[0];
String outputHash = args[1];
String outputPreparedPdf = args[2];

File input = new File(inputPdf);
if (!input.exists() || !input.isFile()) {
System.err.println("ERROR: Input PDF does not exist at: " + inputPdf);
return;
}

System.out.println("Input PDF found at: " + inputPdf);

PdfReader reader = new PdfReader(inputPdf);
PdfSigner signer = new PdfSigner(reader, new FileOutputStream(outputPreparedPdf), new StampingProperties().useAppendMode());

signer.setFieldName("Signature1");
signer.getSignatureAppearance()
.setReason("Swisscom QES")
.setLocation("DE")
.setReuseAppearance(false)
.setPageNumber(1)
.setPageRect(new Rectangle(0, 0, 0, 0)); // invisible

IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.Adobe_PPKLite, PdfName.ETSI_CAdES_DETACHED);
signer.signExternalContainer(external, 32000);
signer.getDocument().close(); // finalize writing

// Compute SHA-256 hash of prepared PDF
MessageDigest digest = MessageDigest.getInstance("SHA-256");
try (InputStream is = new FileInputStream(outputPreparedPdf)) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
digest.update(buffer, 0, bytesRead);
}
}

String hashBase64 = Base64.getEncoder().encodeToString(digest.digest());
try (FileWriter writer = new FileWriter(outputHash)) {
writer.write(hashBase64);
}

System.out.println("Prepared PDF written to: " + outputPreparedPdf);
System.out.println("SHA-256 hash (Base64): " + hashBase64);
}
}
< /code>
import com.itextpdf.kernel.pdf.*;
import com.itextpdf.signatures.IExternalSignatureContainer;
import com.itextpdf.signatures.PdfSigner;
import com.itextpdf.kernel.pdf.PdfDictionary;
import com.itextpdf.kernel.pdf.PdfName;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.json.JSONObject;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.Security;
import java.util.Base64;

public class SignQES {
public static void main(String[] args) {
if (args.length < 6) {
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];
JSONObject qesJson = new JSONObject(args[4]);
String expectedHash = args[5];

Security.addProvider(new BouncyCastleProvider());

try {
// Read the CMS signature
byte[] signatureBytes = Files.readAllBytes(Paths.get(signatureCmsPath));

// Read the prepared PDF to verify its hash matches
byte[] fileBytes = Files.readAllBytes(Paths.get(inputPdf));
String actualHash = Base64.getEncoder().encodeToString(
MessageDigest.getInstance("SHA-256").digest(fileBytes)
);
System.out.println("Java hash before signing: " + actualHash);
System.out.println("Expected hash: " + expectedHash);

if (!actualHash.equals(expectedHash)) {
throw new RuntimeException("Hash mismatch! Expected: " + expectedHash + ", Got: " + actualHash);
}

// Reopen the prepared PDF to inject the actual signature
PdfReader reader = new PdfReader(inputPdf);
reader.setUnethicalReading(true); // needed if pre-signed with external tool
PdfDocument doc = new PdfDocument(reader);
FileOutputStream finalOutput = new FileOutputStream(outputPdf);

// Signature container that returns the Swisscom CMS
IExternalSignatureContainer realContainer = new IExternalSignatureContainer() {
@Override
public byte[] sign(InputStream data) {
return signatureBytes;
}

@Override
public void modifySigningDictionary(PdfDictionary signDic) {
// Already prepared, nothing to modify here
}
};

// Inject the signature into the pre-allocated space
PdfSigner.signDeferred(doc, "Signature1", finalOutput, realContainer);

System.out.println("QES signature written to: " + outputPdf);

} catch (Exception e) {
System.err.println(" Signing failed: " + e.getMessage());
e.printStackTrace();
System.exit(2);
}
}
}
< /code>
Ich habe es ausprobiert: < /p>
  • Verifiziert useAppendMode () wird während der Vorbereitung und Signierung eingestellt. /> < /li>
    Verwendet dasselbe output_prepared.pdf für Hashing und Signierung. Nach der Verarbeitung findet auf dem PDF zwischen Hashing und Signierung statt. /> < /li>
    < /ul>
    Frage (s): < /p>

    Was könnte dazu führen, dass der SHA-256-Hash des vorbereiteten PDF zwischen dem anfänglichen Hashing und dem endgültigen Signiervertrag ändert. Durch Byterange-ausgeschlossene Teile des PDF, ähnlich wie Ittext es erwartet? /> iText 7.2.5 < /p>
    < /li>
    BouncyCastle 1.70 < /p>
    < /li>
    Swisscom QES -API (ETSI -Format)
    Image
    Image
Everything else is green and gültig.
Alle Ideen oder Arbeitsbeispiele wären zutiefst geschätzt!

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post