PPAPの代わりになるサービスを作ってみたがイマイチになった

## PPAPとは？

PPAPとは、  
(P)パスワードZIPファイルを送り、その後に
(P)パスワードを送る、
(A)暗号化
(P)プロトコル

を表します。

要するに、一般的なネットワーク回線を使ってパスワードZIPファイルが盗聴されれば、 その後に送られるパスワードも盗聴される可能性が高いわけで、意味がないということです。

![send_password_zip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30945/e2b2a15e-f224-cc28-cf7c-b86455571d8e.png)

![send_password.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30945/496c6827-7bce-a05d-e337-142b24acc2b9.png)

昨年の2020年11月には内閣府などでも運用を禁止するなど世間的にも問題になっていて、昨今ではこれを運用していた会社や組織で、廃止などの対応を迫られています。

一部、クラウドサービスを利用して、クラウドサーバーに保存されたデータへのURLリンクを相手に知らせてやり取りする方法に置き換わったりするなどしていますが、これもけっきょく「URLを知らせる」ところで盗聴されてしまえばお終いです。

## なんで代わりが生まれないのだろう？

こういう場合は、たいてい２つの理由しかありません。

* 運用が面倒
* 作るのが面倒

だから、この世にPPAPはいまだにはびこっているし、パスワードZIP運用に代わる、より便利なサービスが現れないのだろう想像できます。

しかし、挑戦してみたくなったんですよね。その代わりのシステムなり、サービスは考えられないかな、と思って、試行錯誤してみました。

## 公開鍵方式を使う

ファイルなどのデータを固めてやり取りするには、いわゆる共通の「パスワード」を用いて行う共通鍵暗号方式ではなくて、互いに鍵を交換する公開鍵暗号方式を使うと良いかなと考えました。

鍵は「暗号鍵」「復号鍵」という対（ペア）で使うことができ、片方の鍵からもう片方の鍵の生成が不可能という仕組みになっています。 つまり、「暗号鍵」は暗号化しかできず、「復号鍵」は復号しかできないということになります。

![key_pair.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30945/9373bec9-6e67-dff7-c4cf-c448fbf2592c.png)

それを送信者は、ローカルで「ペア鍵」を生成し、暗号鍵（公開鍵）だけを相手に渡すことで、復号鍵（秘密鍵）は、手元に残しておくことができます。暗号鍵から復号鍵を生成することは事実上、不可能なので、盗聴者が通信経路上で暗号鍵を入手しても無意味です。

![send_public_key.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30945/1f0b8a93-177f-07d0-d105-c61792d7f878.png)

あとは、ローカルから一度も出たことのない復号鍵（秘密鍵）で、暗号化されたファイルを受け取ってから復号します。

![not_wiretap.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30945/b3cb6521-bc93-1d20-419e-51ce6f95b24f.png)

簡単ですね。

その中でも長年使用されていて、使いやすさと（今のところ）安全性が証明されている「RSA」というアルゴリズムが良さそうです。

大きな数の素因数分解が難しいことから安全性を得ており、このアルゴリズムでの公開鍵と秘密鍵は、 大きな（617桁の）素数のペアによる関数です。暗号文と公開鍵から元のデータを復号するのは、 その二つの素数の積を素因数分解するのに等しいと考えられています。

実は、この公開鍵暗号方式のRSAを使った暗号ソフトは、拙作の[アタッシェケース](https://hibara.org/software/attachecase/)というものがあります。

ただ、ユーザーの方からバグ報告や要望をいただくかぎり、公開鍵暗号方式はあんまりユーザーに使われている感触がありません。

それはたぶん、面倒だからです。

具体的には、「鍵交換」のところでしょう。

## 鍵交換サービスを作ってみる

じゃあ、その鍵交換を簡単に行えるサービスを作れるかもと思いました。RSAでの暗号化プログラミングで培った経験があるので、専用アプリも作れそうです。

そこで、実際に作ってみたのが、AttacheCase.NET です。

AttacheCase.NET
<https://attachecase.net/>

まず、上記サイトにて、***送信者***は、メールアドレスなど必要な情報を入力します。

![1_input_mail_address.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30945/fd53c0ce-5a84-4d85-eee3-db1cf4ab6243.png)

そうすることで、サーバーからアプリのダウンロードURLを入手できます。

次に、その「ダウンロードURL」を、やり取りする相手（***受信者***）に伝えます。

![2_notify_dl_url.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30945/2f078649-4c0f-95ec-c35b-19e5b4ac112d.png)

***受信者***は、そのダウンロードURLから、専用の復号アプリをダウンロードします。

![3_download_app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30945/d0025082-c5a8-55f6-ad7f-585734a8ce99.png)

あとは、***受信者***がダウンロードしたアプリを起動して「送信」ボタンを押すだけです。

![4_launch_app.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30945/58ec77f5-0f91-fcb8-f2a4-5bfaea8b42df.png)

アプリは自動的に、対となる「暗号鍵（公開鍵）」「復号鍵（秘密鍵）」を生成し、 暗号鍵だけを AttacheCase.NET へ送信、それを受けたサーバーは、***送信者***の入力情報を基に 「暗号鍵（公開鍵）」を添付してメールを***送信者***へ送信します。

***送信者***は、AttacheCase.NET から送られてきた「暗号鍵（公開鍵）」でデータファイルを アタッシェケース(フリーソフト) で暗号化して相手に送信します。

![5_send_encrypted_file.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30945/292d6068-45bb-6e4f-a5da-c74ecd9186bd.png)

***受信者***は、送られてきた暗号化ファイルを専用アプリへドラッグ＆ドロップするだけで復号できます。

とまあ、構築してみてはみたものの、実際運用してみると、***受信者***が、

* アプリをダウンロード
* アプリを起動
* 起動し表示されたウィンドウの「送信」ボタンを押す

という一連の動作が、簡単なようにみえて面倒くさいし、「なぜ送信ボタンを押さなければならないのか？」というところで手が止まる可能性があります。

ただ、ここはサイトやアプリデザイン、***送信者***の適切な指示があればクリアできそうではあります。

## 弱点もある

実は、PPAPとも通じる点でもあるのですが、このサービスにも弱点があります。

「ダウンロードURL」を送信するときに一般的なネットワークですと、盗聴者に知られてしまうこともあります。これはクラウドサービスを使ってダウンロードURLを相手に伝えるときにも同じリスクがあります。

![2_wiretapping.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30945/9385cf96-dbfc-084d-450f-887850ea6f97.png)

ここで、不正に取得したパスを利用して、 ***受信者***になりすまして先に 公開鍵（暗号鍵）を送る可能性が考えられます。

![spoofing.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/30945/f220e113-2f7e-5cca-53c3-19fdab5d91e9.png)

ただし、AttacheCase.NET では、公開鍵（暗号鍵）の添付メールは一度しか送信されない仕様になっておりますので、***受信者***が送信ボタンを押して、送信が成功し、暗号化ファイルを受け取れる状態になっているか 電話などの別の手段を使って、確認を取ることをすれば、より安全性は高まります。

また、ダウンロードオプションとして、「ダウンロード回数制限」「ダウンロード可能時間」がありますので、 その設定を行うことでも、盗聴の危険性を減らすことができます。

この辺りはクラウドサービスからダウンロードする際のオプションとしても設定できるところは多いと思います。

## 利便性を取るか、安全性を取るか

けっきょくそういうことになるかと思います。

利便性を最大限にするならば、下手にPPAPを使うくらいなら、ノーガードでファイルをそのまま添付してメールしてしまえば良いわけです。

安全性を求めるなら、公開鍵暗号方式を使って、きちんと鍵交換を行ってからファイルのやり取りを行うべきです。

ただ、一度きりだとか、それほど取引のないようなところへデータを送りたい場合は、その一手間が非常に面倒になってきます。そうなると、どこで折り合いを付けるかになるでしょう。

## 鍵交換サービスをつくってはみたものの、クラウドサービスと変わりないものに

[AttacheCase.NET](https://attachecase.net/) というサービスを作ってはみたものの、けっきょくは「ダウンロードURL」を通知するところが、弱点となって、ほとんどクラウドサービスからダウンロードさせるのと大差がなくなってしまいました。

ただ、こちらのサービスは、クラウドサービスを契約するコストが抑えられるという点だけはオススメできるでしょうか。

公開鍵暗号方式を使うというところまでは良いと思うのですが、これ以上、知恵を絞っても便利なサービスが思いつかない、存在しない、ということからも実現は難しいのでしょうね。

誰か、もうちょい便利で安全性の高いサービスがあったら教えてください！