【AWS KMS】ローカル・lambda上で、それぞれKMSを用いてencrypt&decryptを行う

# 【AWS KMS】ローカル・lambda上で、それぞれKMSを用いてencrypt&decryptを行う

AWS初心者で既存のlambdaプロジェクトに入り、コード改変を行う必要が出てきた。
aws-cliもよくわからん状態で色々やってみたので、その備忘録的。

## KMSって何？？
Key Management Service.
暗号化がスムーズにできるやつ。

## ローカルでencrypt&decrypt
### encryptするためのkeyIdを取得

```:command
$ aws kms list-aliases | grep -1 "<使いたい鍵のalias>"
```

<使いたい鍵のalias>を含む前後1行が表示される。

```:result
{
    "AliasName": "alias/<使いたい鍵のalias>",
    "AliasArn": "arn:aws:kms:ap-northeast-1:***********:alias/<使いたい鍵のalias>",
    "TargetKeyId": "~~~~~~~~~~~~~~~~~~~~~~~~~"
```

### 変数に結果を格納

上記の結果のうち、AliasArnかTargetKeyIdの**いずれか**を環境変数に格納する。　

```:command
# AliasArn
$ export KEYID=arn:aws:kms:ap-northeast-1:***********:alias/<使いたい鍵のalias> 

# TargetKeyId
$ export KEYID=arn:aws:kms:ap-northeast-1:***********:key/~~~~~~~~~~~~~~~~~~~~~~~~~ 
```

### KeyIdを用いてencrypt

```:command
aws kms encrypt --key-id $KEYID --plaintext 'password'
```

```:result
{
  "CiphertextBlob": "AQICAHhPD3PY32D6FMhjkfVLRA+NeKc4i9PzZnuvVW+gVfdbZgH91eCL1o/eTMdUI4KM2NSIAAAAZzBlBgkqhkiG9w0BBwagWDBWAgEAMFEGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQM7yY+K+tyCS+dwvwWAgEQgCSpZgm/KnrB7KeVQw3eqCYBlJP/hxUt5/q6J3eIaBe+/IRvx5k==",
  "KeyId": "arn:aws:kms:ap-northeast-1:351540792571:key/13dc2c62-05fa-425e-9910-3fb450610d93"
}
```

結果からわかるように、encryptされた文字列とその際に用いたKeyIDが出力される。
このencryptされた文字列だけを取り出し、base64デコードしてファイルに保存する。

```:command
aws kms encrypt --key-id $KEYID --plaintext 'password' --query CiphertextBlob --output text | base64 --decode> encrypted.txt
```

sublime textで開いたら、こんな感じだった。ちゃんとバイナリファイルになってる。

```:encrypted.txt
0102 0200 784f 0f73 d8df 60fa 14c8 6391
f54b 440f 8d78 a738 8bd3 f366 7baf 556f
a055 f75b 6601 31d8 9d55 e417 1e8e 0e0d
d04b d4cb 9524 0000 0067 3065 0609 2a86
4886 f70d 0107 06a0 5830 5602 0100 3051
0609 2a86 4886 f70d 0107 0130 1e06 0960
8648 0165 0304 012e 3011 040c a991 30c4
8984 f22c 1912 f3aa 0201 1080 24ac 20a7
5d08 b799 ac6b 2d09 7f42 5f9c 287e ae93
f9ac b7e2 6298 cdf9 fb58 9824 1a1a 3c49
c5
```

vimで開いたら、こんな感じだった。文字化けっぽくて、ちゃんとbase64でエンコーディングできてそう。
<img width="1428" alt="スクリーンショット 2019-10-08 16.31.46.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270898/78f5079f-c108-724a-6cc4-73d30f75d8a7.png">



### decrypt

```:command
aws kms decrypt --ciphertext-blob fileb://encrypted.txt
```

```:result
{
    "KeyId": "arn:aws:kms:ap-northeast-1:***********:key/~~~~~~~~~~~~~~~~~~~~~~~~~",
    "Plaintext": "cGFzc3dvcmQK"
}
```

decryptした結果として返されるPlaintestはbase64でエンコードされているので、base64でデコードして表示させる.
さっきと同じようにdecryptされた文字列だけ取得し、base64でデコードする。

```:command
aws kms decrypt --ciphertext-blob fileb://encrypted.txt --query Plaintext --output text | base64 --decode
```

```:result
password
```
元に戻った。


## リモートからlambda上で、encrypt&decrypt
ちゃんと、lambda上のそのfunctionの変更権限を持ったユーザーと、kms使用権限を持ったロールを与えられたfunctionを用いて、行うこと。


### 環境変数を設定

```:command
$ aws lambda update-function-configuration --function-name <関数名> --environment Variables={ORIGIN='password'}
```

### encryptするためのkeyIdを取得

```:command
$ aws list-aliases | grep -1 "<使いたい鍵のalias>"
```

<使いたい鍵のalias>を含む前後1行が表示される。

```:result
{
    "AliasName": "alias/<使いたい鍵のalias>",
    "AliasArn": "arn:aws:kms:ap-northeast-1:***********:alias/<使いたい鍵のalias>",
    "TargetKeyId": "~~~~~~~~~~~~~~~~~~~~~~~~~"
```

### encrypt&decrypt

```python:lambda_function.py
import os

# for decryption
from base64 import b64decode
import boto3

ORIGIN = os.environ.get('ORIGIN')
# ここに、さっきのkeyId情報を入力
KeyId = 'arn:aws:kms:ap-northeast-1:***********:alias/<使いたい鍵のalias> '
kms = boto3.client('kms')
ENCRIPTED = kms.encrypt(KeyId=KeyId,Plaintext=ORIGIN)['CiphertextBlob']

def lambda_handler(event, context):
    print("--------------------------------------------------------")
   
    print('origin = ' + ORIGIN)
    ENCRIPTED = base64.b64encode(ENCRIPTED).decode('utf-8')
    print('enc='+ENCRIPTED)

    dec = kms.decrypt(CiphertextBlob = b64decode(ENCRYPTED))['Plaintext']
    print('dec = ' + dec) 
```

```:command
$ zip lambda_function.py.zip lambda_function.py
$ aws lambda update-function-code --function-name <関数名> --zip-file fileb://lambda_function.py.zip
```

lambda上で、testを実行。きちんと表示されれば成功

base64に関してまだよくわかってないから、ちゃんとそこらへんも勉強しなくては。。。


[参考記事](https://dev.classmethod.jp/cloud/decrypt-sensitive-data-with-kms-on-lambda-invocation/)