I am using swisscom digital signature service and we have a test account. Well the service requires the hash code the pdf file . We send it with
DIGEST_VALUE=$(openssl dgst -binary -SHA256 $FILE | openssl enc -base64 -A)
and I get a PKCS#7 response. You can decode the my signature response by using this website https://certlogik.com/decoder/ and the signature content is http://not_need_anymore
I have the same problem as follow (because we use the same code)
my response has been with sha256 crypted. Well I am using iText with c# to sign the pdf file. I sign and I see some details (such as reason, location etc).
here is the method that creates a pdf file with a signature field
public static string GetBytesToSign(string unsignedPdf, string tempPdf, string signatureFieldName)
{
if (File.Exists(tempPdf))
File.Delete(tempPdf);
using (PdfReader reader = new PdfReader(unsignedPdf))
{
using (FileStream os = File.OpenWrite(tempPdf))
{
PdfStamper stamper = PdfStamper.CreateSignature(reader, os, '\0');
PdfSignatureAppearance appearance = stamper.SignatureAppearance;
appearance.SetVisibleSignature(new Rectangle(36, 748, 250, 400), 1, signatureFieldName);
//IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
IExternalSignatureContainer external = new ExternalBlankSignatureContainer(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);
PdfSignature external2 = new PdfSignature(PdfName.ADOBE_PPKLITE, PdfName.ADBE_PKCS7_DETACHED);//ADBE_PKCS7_SHA1);
//as pdf name I tried also PdfName.ETSI_RFC3161
//(ref => https://github.com/SCS-CBU-CED-IAM/itext-ais/blob/master/src/com/swisscom/ais/itext/PDF.java)
appearance.Reason = "For archive";
appearance.Location = "my loc";
appearance.SignDate = DateTime.Now;
appearance.Contact = "myemail@domain.ch";
appearance.CryptoDictionary = external2;
var level = reader.GetCertificationLevel();
// check: at most one certification per pdf is allowed
if (level != PdfSignatureAppearance.NOT_CERTIFIED)
throw new Exception("Could not apply -certlevel option. At most one certification per pdf is allowed, but source pdf contained already a certification.");
appearance.CertificationLevel = level;
MakeSignature.SignExternalContainer(appearance, external,30000);
byte[] array = SHA256Managed.Create().ComputeHash(appearance.GetRangeStream());
return Convert.ToBase64String(array);
}
}
}
Actualls I do not use what this method returns. Because it already creates a temp pdf file with signature field.
After that,I give the hash code of this pdf file and get PKCS#7 responde. and then using the following function, I am adding the signature to a pdf (it creates another pdf file).
public static void EmbedSignature(string tempPdf, string signedPdf,
string signatureFieldName, string signature)
{
byte[] signedBytes = Convert.FromBase64String(signature);
using (PdfReader reader = new PdfReader(tempPdf))
{
using (FileStream os = File.OpenWrite(signedPdf))
{
IExternalSignatureContainer external =
new MyExternalSignatureContainer(signedBytes);
MakeSignature.SignDeferred(reader, signatureFieldName, os, external);
}
}
}
the signature parameter in the method, I give p7s file content as follows
string signatureContent = File.ReadAllText(@"mypath\signed_cert.p7s");
signatureContent = signatureContent
.Replace("-----BEGIN PKCS7-----\n", "")
.Replace("-----END PKCS7-----\n","").Trim();
what am I missing or doing wrong?
In contrast to the regular detached signatures which sign the whole signed file, integrated signatures in PDFs sign (and can only sign) everything but the space set aside for the signature itself.
(For more backgrounds read this answer)
Thus, when you after preparing the PDF with a placeholder to embed the signature
you hash too much because your hashing included the (then empty, i.e. filled with '0' characters) placeholder for the actual signature. The method
GetBytesToSign
instead only returns the hash over the signed byte ranges, i.e. everything but the placeholder:You have to either takes this value or similarly hash only everything but the placeholder for the signature.