やりたかったこと
とある案件でExcelが改竄されていないか、簡易的にわかるような方策を講じなければなりませんでした。
「それならブックにパスワードを掛ければいいじゃないか!」
と思い立ち、調べ始めたのがきっかけです。
結論
…と思って調べ始めたものの、ブックにパスワードを掛ける方法はわかりませんでした。
ただし、シートを保護する方法は分かったので、備忘録として残しておきます。
Apache POI 4.1.2の場合
JavaからPOIを扱ってみたところ、Worksheet、Workbookともにロックを掛けることができました。
filename.java
XSSFWorkbookworkbook=newXSSFWorkbook();XSSFSheetsheet=workbook.createSheet("Sample");WriteCell(sheet,0,0,"Hello");// 参考記事:【C#】NPOIを使ってExcelファイルを作成・編集する// ワークシートの保護sheet.protectSheet("password");// ワークブックの保護workbook.lockStructure();workbook.setWorkbookPassword("password",HashAlgorithm.sha256);// ワークブックの書き出しvarout=newFileOutputStream("C:\\hogehoge.xlsx");workbook.write(out);workbook.close();out.close();生成されたExcelファイル"hogehoge.xlsx"を開けると、確かにロックがかかっていました。
NPOI 2.5.1の場合
Worksheetはロックを掛けることができましたが、Workbookにロックを掛ける方法が見つかりませんでした。
※どなたかご存じの方がいらっしゃいましたら、方法をご教示いただけますと幸いです。
ワークシートを保護するサンプルコード
POIの場合とほぼ同じです。
filename.cs
varworkbook=newXSSFWorkBook();ISheetworksheet=workBook.CreateSheet("testSheet1");worksheet.ProtectSheet("password");//シートのパスワードを設定workbook.LockStructure();//ワークブックの構造を保護(ただしパスワードはかからない)stringsrcFileName=@"C:\hogehoge.xlsx";FileStreamstream=(File.Exists(srcFileName))?File.OpenWrite(srcFileName):File.Create(srcFileName));workbook.Write(stream);代替手段
NTFSでフォーマットされているドライブ専用になりますが、System.IO.FileInfoクラスのEncrypt()を使うことで、ファイルに保護を掛けることができます。Encryptするとファイルアイコンに鍵マークがつき、ほかのユーザーが編集すると鍵マークが消えます。
filename.cs
FileInfofileInfo=newFileInfo(@"C:\hogehoge.xlsx");fileInfo.encrypt();適用したファイルにはこんな感じのマークがつきます。
※ファイル名を変えたり、USB(フォーマット:Fat32)やRaspberry Piとやり取りするだけでは鍵マークは消えませんでした。
課題
そもそもWorkbookの保護を外すソフトが存在している以上、仮にパスワード保護できたとしても完全に改竄を防げるわけではないことに留意が必要です。あくまで簡易的な保護、と考える必要があります。