LoginSignup
0
0

More than 1 year has passed since last update.

C#でiText7を使ってPDFファイルのパスワード設定・解除する

Last updated at Posted at 2023-04-08

C#でiText7を使う

C#でiText7を使ってPDFファイルのパスワード設定と解除をやってみました。
巷ではiTextSharpの情報は見かけるのですが、JavaではなくC#のiText7の記事が少ないと思い書いてみました。
iText7iTextSharpの後継版で、.NET6と組み合わせればMacでも使えます。
と言うことで、今回の動作確認は以下の環境で行いました。

  • macOS Ventura 13.2
  • .NET6
  • Visual Studio for Mac 17.6 Preview
  • iText7 7.2.5

iText7は「NuGetパッケージの管理」でインストールしておきます。
スクリーンショット 2023-04-03 22.52.41.png

パスワードを設定する

まずは、パスワードがかかっていないPDFファイルを用意します。そして、それをホームディレクトリに置きます。以下、Macで試したのでファイルパスはMac用ですが、Windowsでもファイルパスを適切に書き換えれば問題なく動作します。
設定するパスワードは、文字列からバイト配列に変換する必要があります。

パスワードを設定する
using iText.Kernel.Pdf;

public void ProtectPdf()
{
    // 以下は各自のホームディレクトリのパスに変えてください
    string targetPdfPath = "/Users/mackohei/hoge.pdf";
    // 以下で作業用一時ファイルのパスを生成
    string tmpPdfPath = GenerateRandomPath(targetPdfPath);

    using (FileStream stream = new(tmpPdfPath, FileMode.Create, FileAccess.Write, FileShare.None))
    using (PdfReader pdfReader = new(targetPdfPath))
    using (PdfWriter pdfWriter = new(stream, new WriterProperties()
        // 以下でパスワードとパーミッションの設定をする
        // パスワードは文字列からバイト配列に変換する
        .SetStandardEncryption(Encoding.Default.GetBytes("password"), Encoding.Default.GetBytes("password"),
            EncryptionConstants.ALLOW_PRINTING | EncryptionConstants.ALLOW_COPY,
            EncryptionConstants.STANDARD_ENCRYPTION_128)))
    {
        // 以下でパスワード付きPDFファイルを生成
        var pdfDoc = new PdfDocument(pdfReader, pdfWriter);
        pdfDoc.Close();
    }
    // 元ファイルを一時ファイルに置き換える
    File.Delete(targetPdfPath);
    File.Move(tmpPdfPath, targetPdfPath);
}

パスワード設定した作業用の一時ファイルを作成し、それを元ファイルと置き換えます。
一時ファイルの完成はPdfDocument生成時に行われます。元ファイルの内容を読み込んだPdfReaderの内容を一時ファイルのPdfWriterに書き込む感じです。

一時ファイルのパスは以下の関数で作成しました。(これは一時ファイルのファイル名の重複を避けるためのもので、今回の記事のテーマとは直接関係ありません)

作業用一時ファイルのパスを生成
public static string GenerateRandomPath(string originalPath)
{
    string dirName = Path.GetDirectoryName(originalPath) ?? "/";
    string extension = Path.GetExtension(originalPath);
    string randomPath;
    Random random = new();
    do
    {
        randomPath = random.NextInt64(1, 9999999999).ToString("D10");
        randomPath = dirName + "/" + randomPath + extension;
    }
    while (File.Exists(randomPath));
    return randomPath;
}

以下にSetStandardEncryptionメソッドのリファレンスを貼っておきます。

パスワードを解除する

パスワード解除も、基本的にパスワード設定と同様の流れです。
ポイントは、PdfReader生成時にパスワード解除が必要なところです。バイト配列に変換したパスワードを渡すことでエラー無く読み込めます。

パスワードを解除する
public void UnprotectPdf()
{
    // 以下は各自のホームディレクトリのパスに変えてください
    string targetPdfPath = "/Users/mackohei/hoge.pdf";
    // 以下で作業用一時ファイルのパスを生成
    string tmpPdfPath = GenerateRandomPath(targetPdfPath);
    // 以下で文字列のパスワードをバイト配列にエンコード
    byte[] bytePassword = System.Text.Encoding.Default.GetBytes("password");

    using (FileStream stream = new(tmpPdfPath, FileMode.Create, FileAccess.Write, FileShare.None))
    // 以下で読み込み用PDFリーダーにバイト配列を渡す
    using (PdfReader pdfReader = new(targetPdfPath, new ReaderProperties().SetPassword(bytePassword)))
    using (PdfWriter pdfWriter = new(stream))
    {
        // 以下でパスワードを除いたPDFファイルを生成
        PdfDocument pdfDoc = new(pdfReader, pdfWriter);
        pdfDoc.Close();
    }
    // 元ファイルを一時ファイルに置き換える
    File.Delete(targetPdfPath);
    File.Move(tmpPdfPath, targetPdfPath);
}

当然ですが、パスワードが対象のPDFファイルに設定されているものと一致しなければエラーとなります。

チュートリアルやリファレンスなど

以上、iText7は色々と簡単にPDF加工ができて便利なライブラリだと思います:rocket:
皆さんも機会があったら、以下などを参考に試してみてください:laughing:

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0