やりたかったこと
とある案件でExcelが改竄されていないか、簡易的にわかるような方策を講じなければなりませんでした。
「それならブックにパスワードを掛ければいいじゃないか!」
と思い立ち、調べ始めたのがきっかけです。
結論
…と思って調べ始めたものの、ブックにパスワードを掛ける方法はわかりませんでした。
ただし、シートを保護する方法は分かったので、備忘録として残しておきます。
Apache POI 4.1.2の場合
JavaからPOIを扱ってみたところ、Worksheet、Workbookともにロックを掛けることができました。
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFSheet sheet = workbook.createSheet("Sample");
WriteCell(sheet, 0, 0, "Hello"); // 参考記事:【C#】NPOIを使ってExcelファイルを作成・編集する
// ワークシートの保護
sheet.protectSheet("password");
// ワークブックの保護
workbook.lockStructure();
workbook.setWorkbookPassword("password", HashAlgorithm.sha256);
// ワークブックの書き出し
var out = new FileOutputStream("C:\\hogehoge.xlsx");
workbook.write(out);
workbook.close();
out.close();
生成されたExcelファイル"hogehoge.xlsx"を開けると、確かにロックがかかっていました。
NPOI 2.5.1の場合
Worksheetはロックを掛けることができましたが、Workbookにロックを掛ける方法が見つかりませんでした。
※どなたかご存じの方がいらっしゃいましたら、方法をご教示いただけますと幸いです。
ワークシートを保護するサンプルコード
POIの場合とほぼ同じです。
var workbook = new XSSFWorkBook();
ISheet worksheet = workBook.CreateSheet("testSheet1");
worksheet.ProtectSheet("password"); //シートのパスワードを設定
workbook.LockStructure(); //ワークブックの構造を保護(ただしパスワードはかからない)
string srcFileName = @"C:\hogehoge.xlsx";
FileStream stream = (File.Exists(srcFileName))
? File.OpenWrite(srcFileName)
: File.Create(srcFileName)
);
workbook.Write(stream);
課題
そもそもWorkbookの保護を外すソフトが存在している以上、仮にパスワード保護できたとしても完全に改竄を防げるわけではないことに留意が必要です。あくまで簡易的な保護、と考える必要があります。
#参考にした記事や資料
- Protect workbook for structure ※結局、未解決のまま終わってますが…
- Java POI Documentation XSSFWorkBook
- 【C#】NPOIを使ってExcelファイルを作成・編集する
編集履歴
(2020.06.20) FileInfoでの暗号化について書いていましたが、当該情報の精査が必要なため、削除しました。