private void signWorker_DoWork(object sender, DoWorkEventArgs e) { Cert myCert = null; string certName = null; string tsaUrl = "http://timestamp.globalsign.com/scripts/timestamp.dll"; // null if unused X509Certificate2 certificateData = certificates[certificateComboSelectedIndex] as X509Certificate2; if (certificateData != null) { certName = ExtractDNField(certificateData.Subject, "CN"); if (certName == null) { certName = certificateData.Subject; // Use fallback } byte[] bytes = certificateData.Export(X509ContentType.Pfx, ""); myCert = new Cert(bytes, "", tsaUrl, "" /* TSA login */, "" /* TSA password */); } else { return; //myCert = new Cert(certificateTextBox.Text, certificatePwdBox.Text, tsaUrl, tsaLogin.Text, tsaPwd.Text); } if (reasonComboText == null) { reasonComboText = ""; } // Copy original to backup file, then sign that back to original file name string outputFile; bool outputFileIsTemporary = false; outputFile = Path.GetFileNameWithoutExtension(inputFileTextText) + ".unsigned" + Path.GetExtension(inputFileTextText); outputFile = Path.Combine(Path.GetDirectoryName(inputFileTextText), outputFile); string inputFile = outputFile; // Create a copy if it does not exist yet (keep original unsigned forever) if (!File.Exists(outputFile)) { File.Copy(inputFileTextText, outputFile); outputFile = inputFileTextText; } else { // We need a different temporary file inputFile = inputFileTextText; outputFile = Path.GetTempFileName(); outputFileIsTemporary = true; } // NOTES: // * Encryption can only be applied before any signatures exist, otherwise existing signatures are broken. // * Encryption requires a non-empty password set, or we'll get problems when opening next time. // * Permissions can only be set together with the encryption status. // => Permissions cannot be changed once a signature exists. // http://stackoverflow.com/q/20008256/143684 // TODO PDFEncryption pdfEnc = new PDFEncryption(); pdfEnc.UserPwd = ""; //pdfEnc.OwnerPwd = "1234"; pdfEnc.OwnerPwd = ""; pdfEnc.Encryption = true; // Use 128 bit instead of 40 bit, but still RC4 // Permissions explanation: http://www.pdflib.com/knowledge-base/pdf-security/permissions/ pdfEnc.Permissions.Add(permissionType.Copy); pdfEnc.Permissions.Add(permissionType.DegradedPrinting); pdfEnc.Permissions.Add(permissionType.Printing); pdfEnc.Permissions.Add(permissionType.ScreenReaders); //pdfEnc.Permissions.Add(permissionType.Assembly); pdfEnc.Permissions.Add(permissionType.FillIn); // Includes signing //pdfEnc.Permissions.Add(permissionType.ModifyAnnotation); //pdfEnc.Permissions.Add(permissionType.ModifyContent); // Sign document PDFSigner pdfs = new PDFSigner(inputFile, outputFile, myCert, metaData); PDFSignatureAP sigAp = new PDFSignatureAP(); sigAp.SigReason = reasonComboText; sigAp.SigContact = ""; sigAp.SigLocation = ""; sigAp.Visible = visibleSignatureCheckChecked; sigAp.Multi = existingSignatures; sigAp.Page = pageNumValue; sigAp.CustomText = ""; if (visibleSignatureCheckChecked) { if (showName) { if (showLabels) { sigAp.CustomText += "Digital signiert von "; } sigAp.CustomText += certName + "\n"; } if (showLocation) { string country = ExtractDNField(certificateData.Subject, "C"); string locality = ExtractDNField(certificateData.Subject, "L"); if (!string.IsNullOrEmpty(country) || !string.IsNullOrEmpty(locality)) { if (showLabels) { sigAp.CustomText += "Ort: "; } sigAp.CustomText += locality + (!string.IsNullOrEmpty(locality) && !string.IsNullOrEmpty(country) ? ", " : "") + country + "\n"; } } if (showReason) { if (showLabels) { sigAp.CustomText += "Grund: "; } sigAp.CustomText += reasonComboText + "\n"; } if (showDate) { if (showLabels) { sigAp.CustomText += "Datum: "; } sigAp.CustomText += DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss K") + "\n"; } sigAp.CustomText = sigAp.CustomText.TrimEnd(); if (showImage && signaturePictureImage != null) { using (MemoryStream ms = new MemoryStream()) { signaturePictureImage.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp); sigAp.RawData = ms.ToArray(); } } sigAp.SigX = mm2pt(leftNumValue); sigAp.SigY = mm2pt(bottomNumValue); sigAp.SigW = mm2pt(widthNumValue); sigAp.SigH = mm2pt(heightNumValue); } // Encrypt only if no signatures exist. Later it won't work anymore because it'll // break the existing signatures. pdfs.Sign(sigAp, false /*!existingSignatures*/, pdfEnc); if (outputFileIsTemporary) { // Delete input file and replace with temp output File.Delete(inputFile); File.Move(outputFile, inputFile); } }