1
1

More than 1 year has passed since last update.

PyPDF2でpdfを暗号化・復号する

Last updated at Posted at 2022-11-09

動作環境

python -V

# 実行結果
Python 3.11.0

PyPDF2をインストールします

pip install PyPDF2

pdfファイルを暗号化する

イメージとしてはpdfファイルを新規で作成し、元データを読み込んで、暗号化して保存するような流れになります。
実行すると元データと同じ場所に{ファイル名}_enc.pdfが作成されます。

# モジュールのインポート
from PyPDF2 import PdfFileWriter,PdfFileReader

# 対象のpdfファイルの指定
filename = "./sample.pdf"

#PdfFileWriterオブジェクトを作成
out = PdfFileWriter()

#指定したPDFファイルをPdfFileReaderで開く
file = PdfFileReader(filename)

#PDFファイルのページ数を取得
num = file.numPages

#PDFファイルの全てのページを読み込んで新しいファイルにページを追加する
for idx in range(num):
    page = file.getPage(idx)
    out.addPage(page)

#パスワードを指定
password = 'hogehoge'

#入力したパスワードで新しいファイルを暗号化
out.encrypt(password)

#暗号化された情報をファイルに書き込み
with open(filename.replace('.pdf','') + r'_enc.pdf','wb') as f:
    out.write(f)

pdfファイルにパスワードが設定されているか確認する

isEncryptedを使用してpdfファイルにパスワードが設定されているかを確認します。
パスワードが設定されているとTrueが返され、設定されていないとFlaseが返されます。

# モジュールのインポート
from PyPDF2 import PdfFileReader

# 対象のpdfファイルの指定
enc_file_path = "./sample_enc.pdf"
pdf_file_path = "./sample.pdf"

# pdfファイルのパスワードの有無を出力
print(PdfFileReader(enc_file_path).isEncrypted)
print(PdfFileReader(pdf_file_path).isEncrypted)

# 実行結果
True
False

pdfファイルを復号する

イメージは暗号化の際と同じで、暗号化されていないファイルを新規で作る流れになります。
実行すると元データと同じ場所に{ファイル名}_dec.pdfが作成されます。

# モジュールのインポート
from PyPDF2 import PdfFileReader,PdfFileWriter

# 対象のpdfファイルの指定
file_path = "./sample_enc.pdf"

#PdfFileWriterオブジェクトを作成
out = PdfFileWriter()

#暗号化されたPDFファイルを指定しPdfFileReaderで開く
file = PdfFileReader(file_path)

#PDFファイルに設定したパスワード
password = 'hogehoge'

#パスワードで復号する
file.decrypt(password)

#新しいファイルにページを追加する
for idx in range(file.numPages):
    page =file.getPage(idx)
    out.addPage(page)

#復号された情報をファイルに書き込み   
with open(file_path.replace(r'.pdf','') + r'_dec.pdf','wb') as f:
    out.write(f)

応用

enc.pyにて設定するパスワードを自動で生成して設定します。設定されたパスワードはcsvファイルで吐き出されます。
対象ファイルを実行時の引数から受け取っています。
enc.pycheck_enc.pyでは第一引数に対象ファイル。
dec.pyでは第一引数に対象ファイルと第二引数にパスワードとなっています。

下記のようにファイルを配置します。

.
├── check_enc.py
├── dec.py
├── enc.py
└── pdf
    └── sample.pdf
# check_enc.py

# モジュールのインポート
from PyPDF2 import PdfFileReader
from sys import argv

print(PdfFileReader(argv[1]).isEncrypted)
# enc.py

# モジュールのインポート
from PyPDF2 import PdfFileWriter,PdfFileReader
from os import path
from sys import argv
from re import sub
from string import ascii_uppercase,ascii_lowercase,digits
from secrets import choice

# パスワードを生成する関数を作成
def pwgen(size=20):
   chars = ascii_uppercase + ascii_lowercase + digits + '%&$#()'
   return ''.join(choice(chars) for x in range(size))

#コマンドからの引数を取得
filename = argv[1]

#PdfFileWriterオブジェクトを作成
out = PdfFileWriter()

#指定したPDFファイルをPdfFileReaderで開く
file = PdfFileReader(filename)

#PDFファイルのページ数を取得
num = file.numPages

#PDFファイルの全てのページを読み込んで新しいファイルにページを追加する
for idx in range(num):
    page = file.getPage(idx)
    out.addPage(page)

#パスワードを作成
password = pwgen()

#入力したパスワードで新しいファイルを暗号化
out.encrypt(password)

#暗号化された情報をファイルに書き込み
with open(filename.replace('.pdf','') + r'_enc.pdf','wb') as f:
    out.write(f)

#設定したパスワードをテキストに書き出す
pw_file = lambda x: sub(r'^.*/','',x.replace(r'.pdf','')) + r'_pw.csv'
filecheck = lambda x: 'a' if path.isfile(pw_file(x)) else 'x'

with open(pw_file(filename), filecheck(filename)) as f:
    print("\"" + filename + "\"" + r',' + "\"" + password + "\"", file=f)
# dec.py

# モジュールのインポート
from PyPDF2 import PdfFileReader,PdfFileWriter
from sys import argv

#PdfFileWriterオブジェクトを作成
out = PdfFileWriter()

#暗号化されたPDFファイルを指定しPdfFileReaderで開く
file = PdfFileReader(argv[1])

#PDFファイルに設定したパスワード
password = argv[2]

#パスワードで復号する
file.decrypt(password)

#新しいファイルにページを追加する
for idx in range(file.numPages):
    page =file.getPage(idx)
    out.addPage(page)

#復号された情報をファイルに書き込み   
with open(argv[1].replace(r'.pdf','') + r'_dec.pdf','wb') as f:
    out.write(f)

まとめ

あとはfor文なりでフォルダ内のpdfファイル全てを暗号化・復号するといったことも可能になるので、効率化の参考になれば幸いです。

1
1
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
1
1