「備忘録」パスワード保護Excel作成と読込自動化検討のメモ

>検討中の要件で、Workbook全体のパスワード設定＆暗号化のExcelファイルの作成と読込の自動化の検討が必要になったため、現状のシステムで埋め込めるのかを調べるために整理しておいた内容です。

> 調査・検証内容上、間違いが、もっといい案があるかもなので、参考までにみてください。（筆者も、後ほど時間あれば、もっと検証したいと思ってます）

> もし、過ちがあれば、コメントいただけると嬉しいです。

# 結論

### パスワード保護Excelの作成には、nodeベースの「Secure Spreadsheet」を使う

https://github.com/ankane/secure-spreadsheet

```sh
npm install -g secure-spreadsheet

# CSV to Password Protected Encrypted XLSX
cat input.csv | secure-spreadsheet --password secret > output.xlsx

# XLSX to Password Protected Encrypted XLSX
cat input.xlsx | secure-spreadsheet --password secret --input-format xlsx > output.xlsx
```

### パスワード保護Excelの読込・解除には、pythonベースの「msoffcrypto-tool」を使う

https://pypi.org/project/msoffcrypto-tool/

```py
pip install msoffcrypto-tool

msoffcrypto-tool encrypted.xlsx decrypted.xlsx -p Passw0rd
```

# 背景

施策の要件で、パスワード保護Excelを使って、先方とやりとりをするのが必須

- Excelファイルにパスワードをかけて、先方に送信
- 先方の処理結果を、パスワード保護Excelで受信

を、人のてでするか、自動化するかの選択で「OSSだけで自動化できるか？」の疑いから、検証にいたる

# ベースシステム

php 5.3のBackofficeシステム。

php 7のapiサーバーがあるものの、機能追加するシステムとは分かれているので、 php5.3ベースでやりたいことが前提となっていた。

# 調べた内容と出た課題

## ライブラリー別比較

| library | platform | パスワード保護Excel作成 | パスワード保護Excel読込 | 補足
|---------|---------|---------|---------|---------|---------|----|
| ★ msoffcrypto-tool | Python | 支援X | O | 復号専用
| ★ Secure Spreadsheet | Node | O | 支援X | 暗号化専用
| PHPExcel | PHP >= 5.x |  ※１動作異常 | 支援X | 数年前にサポート終了
| PHPSpreadsheet | PHP >= 7.x | 検証していない | 支援X | PHP7以上必須
| openpyxl | Python | ※１動作異常 | 支援X | msoffcrypto-toolと並行すると、読込可能
| apache poi | Java | 検証していない | 検証していない | ドキュメント上では、サポート可能に見える（IF提供している模様）

> ※１動作異常
> プログラム的にエラーなくちゃんと回って、ファイルも生成されるが、実際にMacのNumbersで開いてみると、保護されてなかったため、保護が正常に聞いていないと判断した。


## ログ

### PHP5.3では、最新のExcelライブラリーが使えない。
PHPには「PHPExcel」と「PHPspreadsheet」の二つのライブラリーが存在する

PHPExcelは5.3で使えるが、何年前にサポート中断されている。
公式的にPhpspreadsheetを使うように推奨されている

しかしPhpspreadsheetは、php7以上じゃないと使えない。

### 「PHPExcel」と「PHPspreadsheet」のどっちも、ちゃんとしたパスワード保護Excelのサポートをしていない

個別のsheet, cellの保護はサポートしているように見えるが、Workbook全体のパスワード設定＆暗号化はサポートしていない。

作成の場合はエラーとかも出ずちゃんとファイルも作られるが、保護がされてなく、MacのNumbersプログラムで開くと、保護が効かず、パスワードなして閲覧・編集ができてしまう。

なので、パスワード保護がうまく効かないと判断。


> - 「個別のsheet, cell」の保護機能
>    - サポートしているように見える
> - ★「Workbook全体暗号化＆パスワード保護」作成
>    - 機能は提供しているみたいだが、ちゃんと動作しないというissueがあった。
>    - https://github.com/PHPOffice/PHPExcel/issues/442
>    - 実際検証してみたところ、ちゃんと保護されない。
>    -  「PHPExcel_Reader_Excel2007」か、「PHPExcel_Writer_Excel2007」を使うことを推奨しているが、それでもダメだった。
> - ★「Workbook全体暗号化＆パスワード保護」読込
>    - サポートしていない

※ PHPSpreadsheetでの、パスワード保護Excel作成は試してないが、読込をサポートしてないので、除外した。


### PHPでは、できないと思って、Pythonの、「openpyxl」と、「msoffcrypto-tool」を組み合わせて、作成と読込ができると思ったが、作成の方はできなかった。

openpyxlの場合は、Workbook全体のパスワード設定＆暗号化の関数は用意されているように見えるが、うまく動作しなかった。

関連stack overflow
https://stackoverflow.com/questions/36122496/password-protecting-excel-file-using-python

issueもあった気がするが、忘れた。

### JavaやNETの、有料ライブラリーもあったが、有料は選定条件から外した。

https://www.easyxls.com/

これだと、いろいろちゃんとサポートしているんじゃないかなと思うが、有料なので、選定から外した。
https://www.easyxls.com/manual/tutorials/java/encrypt-excel-file.html

ただ、読み込みができるかは不明


### 結局Shell上で実行する方針で考えたところ、NODEとPYTHONで、簡単に暗号化＆復号ができることがわかった。

- nodeベースの「Secure Spreadsheet」は、暗号化専用
- pythonベースの「msoffcrypto-tool」は、復号専用

二つを組み合わせて使うと、動作確認＆検証ができた。

### GoogleSheet APIでも、excelの暗号化＆復号はサポートしていない

GoogleSheetで、Native Excelがサポートされたので、ひょっとしてだと思ったが、
ざっくり探してみたが、やはりサポートしていない＆予定も未定だった

### Javaの場合は、Apache POIを検討

また検証はしていないが、Javaなら、これで行けるかも。後で時間あれば検証する


https://poi.apache.org/
https://stackoverflow.com/questions/8817290/create-a-password-protected-excel-file-using-apache-poi
https://github.com/Icemanbeta/PHP-POI