StackOverflow上的以下问题和答案显示了如何生成在没有适当密码的情况下无法打开的PDF。
Password protected PDF using C#
我想类似地使用这个框架,但略微修改以允许我的用户在不需要密码的情况下“打开”PDF,但只允许他们在拥有密码的情况下编辑PDF。
iTextSharp可以吗?
如果这很重要,我在WF 4.0自定义活动中使用C#4.0。
答案 0 :(得分:28)
是的,您可以将两个密码传递给PdfEncryptor.Encrypt()
,userPassword
和ownerPassword
。只需将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);
}
}
答案 1 :(得分:1)
另一种实施方式:
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);
}