前情提要
筆者這邊有一個需求是,pdf檔案在上傳時就判斷好是否有加密,避免後面流程中需要解析pdf檔案時,遇到解密的問題,因此為避免後面流程複雜去防呆,直接於上傳檔案時築一道防線擋掉,是最佳解。筆者在搜尋了一下c# detect password protected pdf的關鍵字時,基本上會跳出使用iTextSharp的解法,筆者就參考此解法寫一個Extension,主要都是參考StackOverFlow的解法,程式碼本身沒甚麼變動,此篇以解釋為準。
內容
筆者這邊驗證的方式使用Linqpad也程式碼片段,因此測試過程需要
- 使用
Microsoft Word製作一個包含簡單內容的文件,已另存新檔案的方式存成pdf檔案 - 透過
pdf加密程式碼片段,產生已加密的pdf檔案 - 透過偵測是否加密的程式碼片段,偵測該
pdf檔案是否有加密
接著在講述一下iTextSharp的License,5.0以下才是標示LGPL的License,且已經無法在nuget上面搜尋得到,好佳在網路上的大神們,有把iTextSharp的4.1.6版本(LGPL)轉成dotnet core版本,因此筆者才得以在dotnet core專案上使用。
https://github.com/VahidN/iTextSharp.LGPLv2.Core
製作Test.pdf
筆者這邊使用敘述的方式,基本上打開word軟體後,寫一些簡單內容,1234之類的,接著使用另存新檔的方式,存檔至桌面,副檔名選擇pdf格式,並且將檔案命名為Test.pdf備用。
製作Test_enc.pdf
接著因為筆者環境本身沒有pdf加密軟體,只好用iTextSharp的程式片段來製作加密檔案
1 | string WorkingFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); |
筆者這邊就密碼設定為1234,產生一個輸入密碼才能打開的pdf檔案,名為Test_enc.pdf備用。
撰寫判斷pdf檔案是否加密
iTextSharp有一個方法可以呼叫,是IsEncrypted(),而此方法會回傳bool型別的結果,然而若會加密檔案則會得到BadPasswordException,然而基本上只要宣告PdfReader實體,基本上就會爆一樣的Exception,因此只要利用宣告PdfReader實體,得到BadPasswordException則表示有密碼保護,用這個原理判斷即可。
1 | public static class PdfExtension |
寫完Extension方法後,在Linqpad中的Main中呼叫其對應方法即可得到是否有加密的判斷結果,我們利用上個步驟的兩個檔案即可。
1 | void Main() |
結論
真的是要感謝網路上的資源,但是要自己要有判斷能力,且不得不推Linqpad的偉大,透過Linqpad,能夠快速驗證腦中的想法及程式碼片段,不需要透過整個API生命週期,才能測試你的想法,非常易用,且付費版本是一次付,終生有效,非常值得購買,這篇就到這了,希望幫助到有跟我一樣需求的大家。
參考
- https://stackoverflow.com/questions/11298651/checking-if-pdf-is-password-protected-using-itextsharp
- https://stackoverflow.com/questions/6586346/itextsharp-password-protected-pdf