2011-07-05 60 views
11

StackOverflow上的以下问题和解答显示如何生成无法在没有适当密码的情况下打开的PDF。iTextSharp密码保护PDF

Password protected PDF using C#

我想同样使用这个框架,但略有改变,让我的用户“打开” PDF无需密码,但只允许他们编辑的PDF,如果他们有密码。

iTextSharp可以吗?

如果这个问题,我正在使用C#4.0在WF 4.0自定义活动中工作。

+1

不,这其实并不重要。但如果任何iTextSharp类对公寓模型敏感,则可能必须在执行活动期间控制线程。 – Will

回答

24

是的,有两个密码可以传递给PdfEncryptor.Encrypt(),userPasswordownerPassword。只需将null传递给userPassword,人们就可以在不指定密码的情况下打开它。

 string WorkingFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); 
     string InputFile = Path.Combine(WorkingFolder, "Test.pdf"); 
     string OutputFile = Path.Combine(WorkingFolder, "Test_enc.pdf"); 

     using (Stream input = new FileStream(InputFile, FileMode.Open, FileAccess.Read, FileShare.Read)) 
     { 
      using (Stream output = new FileStream(OutputFile, FileMode.Create, FileAccess.Write, FileShare.None)) 
      { 
       PdfReader reader = new PdfReader(input); 
       PdfEncryptor.Encrypt(reader, output, true, null, "secret", PdfWriter.ALLOW_SCREENREADERS); 
      } 
     } 
+0

谢谢。我现在要测试一下。 –

0

另一种实现:

public static void Common_PassWordProtectPDF_Static_WithoutEmail(FileInfo[] filteredfiles, string strAgentName, string strAgentCode, string strpassword, string strEmailID, string sourcefolder, string strdestfolder, string strdestinationFileName) 
{ 
    foreach (FileInfo file in filteredfiles) 
    { 
     //string sourcePdf = Convert.ToString(ConfigurationManager.AppSettings["SourceFolder"]) + "\\" + file.Name; 
     //string strdestPdf = Convert.ToString(ConfigurationManager.AppSettings["DestinationFolder"]) + file.Name; 

    string sourcePdf = sourcefolder + "\\" + file.Name; 
    string strdestPdf = strdestfolder + strdestinationFileName; 

    using (Stream input = new FileStream(sourcePdf, FileMode.Open, FileAccess.Read, FileShare.Read)) 
    { 
     //sourcePdf unsecured PDF file 
     //destPdf secured PDF file 

     using (Stream output = new FileStream(strdestPdf, FileMode.Create, FileAccess.Write, FileShare.None)) 
     { 
      PdfReader pdfReader = new PdfReader(input); 
      X509Store store = new X509Store("My"); 
      store.Open(OpenFlags.ReadOnly); 

      X509Certificate2 cert = new X509Certificate2(); 
      RSACryptoServiceProvider csp = null; 
      AcroFields fields = pdfReader.AcroFields; 

      foreach (X509Certificate2 mCert in store.Certificates) 
      { 
       //TODO's 
       string strresult = mCert.GetName(); 
       bool str123 = false; 
       if (strresult.Contains("Certificate name") == true) 
       { 
        csp = (RSACryptoServiceProvider)mCert.PrivateKey; 

        SHA1Managed sha1 = new SHA1Managed(); 
        UnicodeEncoding encoding = new UnicodeEncoding(); 
        byte[] data = encoding.GetBytes(file.Name); 
        byte[] hash = sha1.ComputeHash(data); 

        // Sign the hash 

        byte[] signature = csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1")); 

        if (Verify(file.Name, signature, mCert)) 
        { 
         char s = pdfReader.PdfVersion; 
         //var pdfStamper = PdfStamper.(pdfReader, output, s, @"\0", true); 
         //csp.SignData(signature, true); 
         pdfReader.Appendable = false; 

         Org.BouncyCastle.X509.X509CertificateParser cp = new Org.BouncyCastle.X509.X509CertificateParser(); 
         Org.BouncyCastle.X509.X509Certificate[] chain = new Org.BouncyCastle.X509.X509Certificate[] { 
    cp.ReadCertificate(mCert.RawData)}; 

         IExternalSignature externalSignature = new X509Certificate2Signature(mCert, "SHA-1"); 


         // var signedPdf = new FileStream(output, FileMode.Create); 
         // var signedPdf = PdfEncryptor.Encrypt(pdfReader, output, true, strpassword, strpassword, PdfWriter.ALLOW_PRINTING); 
         //char s = pdfReader.PdfVersion; 
         var pdfStamper = PdfStamper.CreateSignature(pdfReader, output, s, @"\", false); 
         PdfSignatureAppearance signatureAppearance = pdfStamper.SignatureAppearance; 

         byte[] USER = Encoding.ASCII.GetBytes("userpwd"); 
         byte[] OWNER = Encoding.ASCII.GetBytes(strpassword); 

         Rectangle cropBox = pdfReader.GetCropBox(1); 
         float width = 108; 
         float height = 32; 

         // signatureAppearance.SignatureGraphic = Image.GetInstance("C:\\logo.png"); 
         //signatureAppearance.Layer4Text = "document certified by"; 
         //signatureAppearance.Reason = "Because I can"; 
         //signatureAppearance.Location = "My location"; 
         //signatureAppearance.SetVisibleSignature(new Rectangle(100, 100, 250, 150), pdfReader.NumberOfPages, "Signature"); 

         Rectangle rect = new Rectangle(600, 100, 300, 150); 
         Chunk c = new Chunk("A chunk represents an isolated string. "); 
         rect.Chunks.Add(c); 
         //signatureAppearance.SetVisibleSignature(new Rectangle(100, 100, 600, 150), pdfReader.NumberOfPages, "Signature"); 

         signatureAppearance.SetVisibleSignature(rect, pdfReader.NumberOfPages, "Signature"); 

         // signatureAppearance.SetVisibleSignature(new Rectangle(cropBox.GetLeft(0), cropBox.GetBottom(0), cropBox.GetLeft(width), cropBox.GetLeft(height)), pdfReader.NumberOfPages, "Signature"); 

         signatureAppearance.SignatureRenderingMode = PdfSignatureAppearance.RenderingMode.DESCRIPTION; 
         pdfStamper.SetEncryption(USER, OWNER, PdfWriter.AllowPrinting, PdfWriter.ENCRYPTION_AES_128); 
         MakeSignature.SignDetached(signatureAppearance, externalSignature, chain, null, null, null, 0, CryptoStandard.CMS); 

         pdfStamper.Close(); 


         // PdfEncryptor.Encrypt(pdfReader, output, true, strpassword, strpassword, PdfWriter.SIGNATURE_EXISTS); 
        } 
        else 
        { 
         Console.WriteLine("ERROR: Signature not valid!"); 
        } 
       } 
      } 

      string Password = strpassword; 

     } 
    } 
} 




public static byte[] Sign(string text, string certSubject) 
{ 

    // Access Personal (MY) certificate store of current user 

    X509Store my = new X509Store(StoreName.My, StoreLocation.CurrentUser); 

    my.Open(OpenFlags.ReadOnly); 

    // Find the certificate we’ll use to sign 

    RSACryptoServiceProvider csp = null; 

    foreach (X509Certificate2 cert in my.Certificates) 
    { 

     if (cert.Subject.Contains(certSubject)) 
     { 
      // We found it. 

      // Get its associated CSP and private key 
      csp = (RSACryptoServiceProvider)cert.PrivateKey; 
     } 

    } 

    if (csp == null) 
    { 
     throw new Exception("No valid cert was found"); 
    } 

    // Hash the data 

    SHA1Managed sha1 = new SHA1Managed(); 

    UnicodeEncoding encoding = new UnicodeEncoding(); 

    byte[] data = encoding.GetBytes(text); 

    byte[] hash = sha1.ComputeHash(data); 

    // Sign the hash 

    return csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1")); 

} 

    static bool Verify(string text, byte[] signature, X509Certificate2 cert) 
    { 

     // Load the certificate we’ll use to verify the signature from a file 

     // X509Certificate2 cert = new X509Certificate2(certPath); 

     // Note: 

     // If we want to use the client cert in an ASP.NET app, we may use something like this instead: 

     // X509Certificate2 cert = new X509Certificate2(Request.ClientCertificate.Certificate); 

     // Get its associated CSP and public key 

     RSACryptoServiceProvider csp = (RSACryptoServiceProvider)cert.PublicKey.Key; 

     // Hash the data 

     SHA1Managed sha1 = new SHA1Managed(); 

     UnicodeEncoding encoding = new UnicodeEncoding(); 

     byte[] data = encoding.GetBytes(text); 

     byte[] hash = sha1.ComputeHash(data); 

     // Verify the signature with the hash 

     return csp.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), signature); 
} 
+0

我还没有读过这个,但我改变了格式,因为代码很难阅读。 –

+1

@PrafullHowal您使用至少十倍于Chris实现使用的代码行数来呈现*“另一个实现”*。这不完全是一个优势。您的实施必须考虑使用它的哪些优势? – mkl