mkcert(オレオレ証明書)を使ってローカル環境へiPhoneからhttps接続する

##はじめに
先日Zennに以下の記事を投稿しました。

https://zenn.dev/takumiabe21/articles/366f519cdf97a2

クレジットカードの読み取り機能を使用する為には、ローカル環境にhttps接続する必要があり、ngrokというライブラリを使用して、https接続を実現しました。
このZennの記事で、ngrokの使用について以下のコメントを頂きました。(ありがとうございます！)
>ローカル環境でSSL使う場合mkcertを使う方が安全かもしれません。
>情報はググれば結構出てくると思います。

なので、mkcertでhttps接続をやってみようと思いこの記事を書きました！

##環境
```
macOs Catalina バージョン 10.15.7
iOS 14.4.2
```
※サンプルのアプリケーションはAngularを使用したアプリケーションです。

##やっていく

やる事は主に以下になります。
・mkcertのインストール
・ローカル認証局（CA）のインストール
・証明書と秘密鍵を作成
・トラストストアにローカル認証局（CA）をインストール
・"ng serve"を使用してHTTPS経由でAngularアプリケーションを起動
・iPhoneのSafariからHTTPS接続

<br>

**○mkcertのインストール**
Homebrewを使ってインストールします。

```bash
$ brew install mkcert
```
インストールが出来ているか確認。

```bash
$ mkcert --version
v1.4.3
```
<br>

**○ローカル認証局（CA）のインストール**

```bash
# ローカル認証局用ののディレクトリを作成  ※作成は必須ではありません。
$ cd
$ mkdir mkcert
$ cd mkcert

# ローカル認証局のインストール
$ mkcert install
Created a new local CA 💥
Note: the local CA is not installed in the system trust store.
Run "mkcert -install" for certificates to be trusted automatically ⚠️

Created a new certificate valid for the following names 📜
 - "install"

The certificate is at "./install.pem" and the key at "./install-key.pem" ✅

It will expire on 8 August 2023 🗓

```
<br>

**○証明書と秘密鍵を作成**

```bash
# ※証明書, 秘密鍵用のディレクトリを作成　 ※作成は必須ではありません。
$ mkdir mkcert/ssl
$ cd mkcert/ssl

#　証明書と秘密鍵を作成 
$ mkcert localhost 192.168.0.7 127.0.0.1  #localhost 現在のIPアドレス ループバックアドレスを指定

Note: the local CA is not installed in the system trust store.
Run "mkcert -install" for certificates to be trusted automatically ⚠️

Created a new certificate valid for the following names 📜
 - "localhost"
 - "192.168.0.7"
 - "127.0.0.1"

The certificate is at "./localhost+2.pem" and the key at "./localhost+2-key.pem" ✅

It will expire on 8 August 2023 🗓
```

※ここでIPアドレスを間違えて指定していた為、接続できず無駄な時間を過ごしました。
間違えていた場合、作成した証明書と秘密鍵を削除して、再度作成したら問題なく動作しました。

<br>

**○トラストストアにローカル認証局（CA）をインストール**

```bash
$ mkcert -install
Sudo password: #macのパスワードを入力
The local CA is now installed in the system trust store! ⚡️
```
<br>

**○"ng serve"を使用してHTTPS経由でAngularアプリケーションを起動**

以下のコマンドを実行してアプリケーションを起動します。

```bash
$ ng serve --host 0.0.0.0 --ssl true --ssl-key ~/mkcert/ssl/localhost+2-key.pem --ssl-cert ~/mkcert/ssl/localhost+2.pem
```
`--host` はiPhoneから接続する為、全てのIPアドレスからの接続を許可します。
`--ssl` はHTTPSでサービスを提供する場合にtrueを指定します。
`--ssl-key` はHTTPSでのサービスに使用する秘密鍵を指定します。(秘密鍵までのパスで指定)
`--ssl-cert` はHTTPSでのサービスに使用するSSL証明書を指定します。(証明書までのパスで指定)

`https://localhost:4200/`でアクセスしたら、下記画像のようにとりあえずPCからのHTTPS接続は上手く出来ました。続いてiPhoneからHTTPS接続をします。

<img width="400" alt="IMG_2544.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497827/3b311665-2a06-ff30-d8b3-3c48fa3e10b4.png">


<br>
**○iPhoneのSafariからHTTPS接続する。**

iPhoneからHTTPS接続する為には、以下の2つの作業が必要になります。
・ルート証明書をiPhoneにインストールする。
・iPhoneでルート証明書を信頼する。
<br>

**・ルート証明書をiPhoneにインストールする。**
Macのキーチェーンアクセスで[システム]を開く。
今回作成した証明書があるので、右クリックしてフォーマット「pem」を選択して、保存する。 (どのフォーマットでも問題ないみたいです。)
保存したファイルをメールに添付するなり、Airdropで送るなりして、iPhoneに送信します。
iphoneでダウンロードが出来たら、[設定]→ [プロファイルがダウンロード済み]を選択。
↓
下記画像のように、ダウンロード済のルート証明書が表示されるはずです。
<img width="400" alt="IMG_2544.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497827/2b3c8ccc-6e56-c3f1-7243-1bd85f1e106a.png">
右上のインストールをクリック。
↓
<img width="400" alt="IMG_2563.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497827/b708726e-c9ad-034e-fd2d-b7136ca12e92.png">
右上のインストールをクリック。
↓
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497827/e5a1bb14-07e6-88be-8611-f5d6be245d6c.png">

インストールが完了しました。続いて、iPhoneでルート証明書を信頼する作業を行います。

<br>
**・iPhoneでルート証明書を信頼する。**
[設定] → [一般] → [情報] → [証明書信頼設定] → ルート証明書を全面的に信頼するの項目で、インストールした証明書をONにします。
<img width="400" alt="IMG_2565.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497827/9e179115-102a-ef2b-60c2-c92b5df03d34.png">

[設定] → [プロファイル]でインストールしたプロファイルを選択するとルート証明書を確認できます。
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497827/f3960e9a-1f5b-bfd1-21a5-c3ba5686c453.png">

この状態で、iPhoneのsafariを開いて、`https://192.168.0.7:4200/`にアクセスします。
<img width="400" alt="IMG_2574.PNG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/497827/93df65ad-23c7-bba4-747d-359ec1f40565.png">

iPhoneのsafariからアクセスできました！

##まとめ
ngrokを使用した方が簡単にhttps接続が可能ですが、証明書は使わず、外部のどこからでもアクセスできてしまう為、セキュリティー的に安全ではないです。
少し手間ですが、証明書を使用したmkcertの方が安全なのでローカル環境にhttps接続する際はmkcertの使用を推奨します！


##参考

○mkcertについて

https://github.com/FiloSottile/mkcert

https://one-it-thing.com/6514/

○iPhoneの証明書の設定について

http://security.data-site.info/291.html

http://security.data-site.info/291.html

○ng serve オプションについて

https://angular.jp/cli/serve