GCP・AWS を利用して手軽に暗号化・復号化をするコマンドラインツールをつくった


# はじめに

* 事故防止のため API のアクセスキーなどのデリケートな情報は Git リポジトリにいれないで別に管理することはよくあると思いますが、安全のためとは言え Git で一元管理できないのは結構面倒です。
* そこでデリケートな情報を安全でお手軽に管理できるようにしたいと思い、cloudkey というコマンドラインツールを作ってみました。

# [cloudkey](https://github.com/nirasan/cloudkey) とは

* GCP や AWS の KMS （暗号鍵管理サービス）を使ってファイルを暗号化・復号化するコマンドラインツールです。
* 暗号化することでデリケートな情報も安全に Git で管理することができるようになり、クラウドの暗号化サービスを使うことで複数の環境や複数のユーザーで手軽に暗号鍵を共有することができます。
* 利用イメージは下図のとおりです。

![usage.png](https://qiita-image-store.s3.amazonaws.com/0/17778/a26e6281-fa9d-f6bf-27fd-b496d8a75cc5.png)

# メリット

## デリケートなファイルの管理を手軽で安全に

* KMS でデリケートなファイルを暗号化することにより Git リポジトリなど公開された環境に安全に保存することが可能になり管理が手軽になります。
* KMS の利用には GCP や AWS のアカウント作成と KMS での暗号鍵の作成が必要になります。例えば GCP や AWS をすでに利用していればアカウントの作成や認証は不要であり、鍵の作成も一度行うだけでよいので、手軽に利用し始めることができます。

## 暗号鍵の管理を手軽で安全に

* KMS に暗号鍵の管理を任せることで手動でファイルのコピーなどをする必要がなくなり暗号鍵の管理が手軽になります。
* また KMS には一定期間ごとに鍵を更新する機能があるので一度作ったきりの鍵をずっと使い回すよりは安全性が高くなります。
* 個人個人に鍵の管理を任せた場合にうっかり漏洩されてしまうリスクを考えれば安全性が高くなると言えるかと思います。

# デメリット

## GCP, AWS を使える環境でしか使えない

* オフラインだったり外部サイトに繋がらない環境だったり各サービスのメンテナンス中だったり GCP や AWS を信用していなかったりだと利用できません。

## 費用がかかる

* GCP KMS は鍵の管理が一つ 0.06 USD/month で暗号化などの操作 10,000 回毎に 0.03 USD なので、普通に使えば 0.09 USD/month くらい。（[料金表](https://cloud.google.com/kms/pricing?hl=ja)）
* AWS KMS は鍵の管理が一つ 1 USD/month で操作 10,000 回毎に 0.04 USD で無料枠が 20,000 回なので、普通に使えば 1 USD/month くらい。（[料金表](https://aws.amazon.com/jp/kms/pricing/)）

# 利用方法

## 概要

1. GCP, AWS のアカウント作成
1. KMS で暗号鍵を作成
1. cloudkey のインストール
1. cloudkey の設定を作成
1. cloudkey を使って暗号化・復号化を実行

## GCP, AWS のアカウント作成

* 作成する

## KMS で暗号鍵を作成する

* [GCP の場合](https://cloud.google.com/kms/docs/quickstart?hl=ja)
* [AWS の場合](http://docs.aws.amazon.com/ja_jp/kms/latest/developerguide/getting-started.html)

## インストール

```bash
go install github.com/nirasan/cloudkey
```

## 設定ファイルを作成する

### GCP で gcloud 認証したアカウントで利用する場合

* GCP SDK の gcloud コマンドを使うとコマンドラインから ID, パスワードのみで認証が可能なので、ローカルに認証情報を保存する必要がないという点で一番手軽な認証方法になります。

```bash
# ログイン
gcloud auth application-default login
# 設定ファイルの作成
cloudkey config gcp gcloud-account --project PROJECT_NAME --location LOCATION --keyring KEYRING_NAME --key KEY_NAME CONFIG_FILE
```

### GCP でサービスアカウントを利用する場合

* GCP のサービスアカウントのキーを使って cloudkey を利用することができます。
* キーをローカルに保持する必要があり gcloud アカウントを使う場合に比べて若干手間にはなりますが、サーバー上など任意の環境で cloudkey コマンドを実行できるようになります。

```bash
# サービスアカウントを作成する -- https://cloud.google.com/iam/docs/creating-managing-service-accounts?hl=ja

# サービスアカウントキーを作成する -- https://cloud.google.com/iam/docs/managing-service-account-keys?hl=ja

# 設定ファイルを作成する
cloudkey config gcp service-account --project PROJECT_NAME --location LOCATION --keyring KEYRING_NAME --key KEY_NAME --service-account-key SERVICE_ACCOUNT_JSON_KEY_FILE CONFIG_FILE
```

### AWS で認証ファイルを使用する場合

* AWS で認証情報の記載されているファイルを使って cloudkey を利用する
* 認証ファイルはあらかじめ作成する必要がある

```bash
# 認証ファイルの作成方法 -- http://docs.aws.amazon.com/en_en/cli/latest/userguide/cli-chap-getting-started.html

# 設定ファイルを作成
cloudkey config aws shared-creds --cred-file CREDENTIAL_FILE --profile PROFILE --region REGION --key KEY_ID CONFIG_FILE
```

### AWS で認証情報を直接指定する場合

* Web の管理画面などから認証情報をコピーして直接入力する場合

```bash
cloudkey config aws static-creds --access-key-id ACCESS_KEY_ID --secret-access-key SECRET_ACCESS_KEY --access-token ACCESS_TOKEN --region REGION --key KEY_ID CONFIG_FILE
```

## 暗号化・復号化を行う

```bash
# 暗号化. extension には暗号化後に付与する拡張子を指定する.
cloudkey encrypt [gcp|aws] --config CONFIG_FILE --extension EXTENSION TARGET_FILE

# 復号化. extension には復号化後に取り除く拡張子を指定する.
cloudkey decrypt [gcp|aws] --config CONFIG_FILE --extension EXTENSION TARGET_FILE

# 再帰的に再暗号化. 対象ディレクトリ内に暗号化済みのファイルがあれば元ファイルを再度暗号化する
cloudkey re-encrypt [gcp|aws] --config CONFIG_FILE --extension EXTENSION TARGET_DIR

# 再帰的に再復号化. 対象ディレクトリ内に暗号化済みのファイルがあれば元ファイルを復号化する
cloudkey re-decrypt [gcp|aws] --config CONFIG_FILE --extension EXTENSION TARGET_DIR
```

# おわりに

* うっかり暗号化前のファイルをリポジトリに入れてしまったりとか GCP や AWS から暗号鍵が漏洩したりとかでセキュリティ事故は起こりえるので基本的に自己責任での使用でお願いします。
* こんなのつくっておいてなんですが個人的にはデリケートなファイルは暗号化してもプライベートリポジトリでなければアップロードはしたくないはしたくないです。