パスワード受け渡し用の Heroku アプリ、 Keydrop というのを作りました

keydrop

Keydrop は、遠隔にいる方からパスワードを (比較的) 安全に受け取るための Heroku アプリケーションです。

必要な時だけ起動して、使い終わったら消す、という使い方を想定しています。

Keydrop がやること

Keydrop はパスワードの

  • 暗号化
  • バリデーション

を行います。実装は PHP です。

暗号化

以下を使います。

  • 送信時: HTTPS https://*.herokuapp.com/...
  • 保存時: htpasswd apr1 形式でハッシュ化、もしくは RSA 公開鍵で暗号化
  • 受信時: PostgreSQL SSL 接続

バリデーション

デフォルトでは、パスワードに以下の制約を設けています。

  • 10 文字以上
  • 最低 1 文字の数字 (0 - 9)
  • 最低 1 文字の半角大文字アルファベット (A - Z)
  • 最低 1 文字の半角記号 (#$%@&*!...)

準備

  1. Heroku のアカウント作成。2段階認証を忘れずに
  2. Heroku のコマンドラインアプリケーションをインストール
  3. PostgreSQL をインストール。Heroku のデータベースに接続するためクライアントだけを使用します。サーバのセットアップは不要です
    • 例: $ brew install postgresql
  4. 公開鍵で暗号化する場合は OpenSSL をインストール

セットアップ

以下のボタンをクリックしてください。

Deploy

以下の設定画面が表示されます。

config

設定: App name

空のままがおすすめです。ランダムなドメイン名が設定されます。

設定: ACCEPT_PATHS

ランダムなパス名を設定してください。コンマで区切って複数のパスを設定できます。

例:

/K7FElrHrPmUnmBdw,/Mfj2Wl2YF6rFcMQ6

URL は以下のような形式になります。

https://${app-name}.herokuapp.com${ACCEPT_PATH}

ACCEPT_PATHS に合致しない URL は 404 になります。

ユーザグループを区別したい場合などに、複数のパス名を設定して、それぞれの URL を伝えてください。

設定: ENCRYPTION_TYPE

暗号化の方式。デフォルトは htpasswd です。

公開鍵で暗号化したい場合は、publickey に設定してください。

設定: PUBLICKEY

ENCRYPTION_TYPE に htpasswd を設定している場合は、変更する必要はありません。

デフォルト値は、GitHub にコミットされている鍵でテスト用です。公開鍵暗号を使う場合は、必ず修正してください。

公開鍵の生成

bin/genkey.sh を使うか、以下のようなコマンドで生成してください。

$ openssl genrsa -aes256 -out private.pem 2048
$ openssl rsa -pubout -in private.pem -out public.pem

URL を伝える

パスワードを送ってほしい相手に、以下を伝えます。

以下の URL にアクセスし、xxxxxxx という ID でパスワードを入力してご連絡ください。

  • https://${app-name}.herokuapp.com${ACCEPT_PATH}

実際のログイン ID ではなく、受け渡し用の仮の ID を使っても構いません。

同じ ID で複数のパスワードがポストされた場合は、2度送信したかどうかを確認してください。他人が別のパスワードを送っている可能性を検討してください。ID が重複しても、ユーザには何も知らせません。

結果を受け取る

./bin/dump.sh を使用します。結果をブラウザで表示する方法はありません。

$ ./bin/dump.sh random-appname-12345
--> Connecting to postgresql-dbname-54321
1       2017-08-30 03:06:57+00  htpasswd        /vEswu2ech4ta   test-1  test-1:$apr1$4.Pz0U/W$TppMU9SjE/W0yg1FAPiMS/
2       2017-08-30 03:08:19+00  publickey       /vEswu2ech4ta   test-2  nJ97fbhHIkZAMISp/zXVETvitUl8Qlbi1pyOTtoF3ybI9EDrqenPFb4WMOISrTn8sW+Qu5xvNsjaMEIC3j0Md+hmtEzlLmVK+Nb9bq989I9TnmjgdtFE9klyKkhb5J7r+7SKqBgzfmu7kAoREYBtg05hvNb3mJXGbAruybElbZlxNgf06b5f6W/kkHtGcJaV49oNHKBEmg03ceMip2wP5H6tk/BS6O4FTrEKvpYsn4+Kh6+7JMioCVQEXz3NvpH0BIkmnGncXBZTdtPihju7srb0uEHe0sys66PPBZGZQWbisBdr9knJ5WTfnh2iWLOGv2NgOwfgXQZyMdizINALDw==

公開鍵暗号の復号もできます。

$ ./bin/dump.sh random-appname-12345 ./keys/insecure-private.pem
--> Connecting to postgresql-dbname-54321
1       2017-08-30 03:06:57+00  htpasswd        /vEswu2ech4ta   test-1  test-1:$apr1$4.Pz0U/W$TppMU9SjE/W0yg1FAPiMS/
2       2017-08-30 03:08:19+00  publickey       /vEswu2ech4ta   test-2  testTEST1234!!!

または、 heroku pg:sql で直接 DB にアクセスしてください。

$ heroku pg:psql --app random-appname-12345
--> Connecting to postgresql-dbname-54321
psql (9.6.1, server 9.6.4)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.

random-appname-12345::DATABASE=> select * from keys;
 id |   type    |     path      | username |                                                                                                                                                                           key                                                                                                                                                                            |       created_at
 ----+-----------+---------------+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------------------------
   1 | htpasswd  | /vEswu2ech4ta | test-1   | test-1:$apr1$4.Pz0U/W$TppMU9SjE/W0yg1FAPiMS/                                                                                                                                                                                                                                                                                                             | 2017-08-30 03:06:57+00
   2 | publickey | /vEswu2ech4ta | test-2   | nJ97fbhHIkZAMISp/zXVETvitUl8Qlbi1pyOTtoF3ybI9EDrqenPFb4WMOISrTn8sW+Qu5xvNsjaMEIC3j0Md+hmtEzlLmVK+Nb9bq989I9TnmjgdtFE9klyKkhb5J7r+7SKqBgzfmu7kAoREYBtg05hvNb3mJXGbAruybElbZlxNgf06b5f6W/kkHtGcJaV49oNHKBEmg03ceMip2wP5H6tk/BS6O4FTrEKvpYsn4+Kh6+7JMioCVQEXz3NvpH0BIkmnGncXBZTdtPihju7srb0uEHe0sys66PPBZGZQWbisBdr9knJ5WTfnh2iWLOGv2NgOwfgXQZyMdizINALDw== | 2017-08-30 03:08:19+00
(2 rows)

公開鍵暗号を手動で復号する場合は、以下を行います。

  1. Base64 デコード $ base64 -D input_file
  2. OpenSSL で復号 $ openssl rsautl -decrypt -inkey privatekey_file -in base64decoded_file

片付け

受け渡しが終わったら、Heroku の管理画面からアプリを削除します。

Heroku の料金体系

Keydrop を使っていて、無料の範囲を超えることは普通はないと思います。

無料のプランでは、30 分アクセスがないとアプリがスリープ状態になり、アクセスが来ると起動します(表示に少し時間がかかります)。月合計で 550 時間 (22日分) まで、クレジットカードを登録すると 1,000 時間 (41日分) まで稼働させることができます。

(2017年9月現在)

qiita.com

www.heroku.com

devcenter.heroku.com