iOS アプリ開発で必要な証明書を openssl を使って作成

## ことの発端

もう、十数年こんな面倒なことやらせて開発者に負担を掛けるのを止めて欲しいが、iOSアプリを開発してると、そうも言ってられない例の ```モノ``` を作ります。[^1]

[^1]: 著者がヘソ曲げてますが、要は iOS 開発で必要になる証明書の作成を一通り記事にしたものです。

## 手順

```Xcode``` で作ったり ```キーチェーンアクセス``` で作ったりする方法がありますが、どちらも、将来バージョンアップして使用方法が変わると面倒なので、 ```openssl``` を使います。（手数的にもそう大差ない気がします）


### 1. 秘密鍵を作成する

下記のコマンドを実行します。

```sh
openssl genrsa -out private.key 2048                  
```

```private.key``` が生成されます。


### 2. CSR を作成する

下記のコマンドを実行します。

```sh
openssl req -new -key private.key -out adc.csr
```

色々聞かれるので適当に入力します。
（全部空白だと拒否られた記憶があるが試してないです）

```sh
Country Name (2 letter code) []:JP
State or Province Name (full name) []:TOKYO
Locality Name (eg, city) []:CHIYODA-KU
Organization Name (eg, company) []:CODIANZ Inc.
Organizational Unit Name (eg, section) []:Development Div.
Common Name (eg, fully qualified host name) []:codianz.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
```

```adc.csr``` が生成されます。


### 3. Apple Developer で証明書を発行する

#### 3-1　Apple Developer にアクセス

未だに、 Apple Developer から、どうやればこの画面に行けるのか分からない。。。

[https://developer.apple.com/account/resources/certificates/list](https://developer.apple.com/account/resources/certificates/list)


#### 3-2. 証明書の作成を開始

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/5fec5138-e86f-382d-146f-43b51760f9ec.png)

``` Certificates(+) ``` をクリックします。


#### 3-3. 証明書の種類を選択

iOS 開発において、主に使う種類は２つです。

1. ```Xcode``` で直接デバイスにデプロイする 開発用
1. Web 経由や ```iTunes``` 経由で配布するアドホック用 （ストア用含む）

開発用は ```iOS App Development``` を選択し、アドホックやストア用は ```iOS Distribution (App Store and Ad Hoc)``` を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/8b0a6428-ba40-f64d-464f-121e618666bb.png)

選択したら ```Continue``` をクリックします。

#### 3-4. CSR ファイルを選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/2140f218-fd43-c5f9-0aa2-a770d17818d6.png)


```Choose File``` をクリックして、２で作成した ```adc.csr``` を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/15a6d790-f3b6-11bc-867e-a530d14a430d.png)

```Continue``` をクリックします。

#### 3-5. 証明書をダウンロード

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1038343/0218a676-abfe-0692-b9e1-4b48a61773c1.png)

```Download``` をクリックします。

開発用は　```ios_development.cer``` 、アドホックやストア用は ```ios_distribution.cer``` という名称でダウンロードされます。

### 4. p12 ファイルを作成

```sh:開発用
openssl x509 -in ios_development.cer -inform DER -out ios_development.pem -outform PEM

openssl pkcs12 -export -inkey private.key -in ios_development.pem -out ios_development.p12
```

```sh:アドホックやストア用
openssl x509 -in ios_distribution.cer -inform DER -out ios_distribution.pem -outform PEM

openssl pkcs12 -export -inkey private.key -in ios_distribution.pem -out ios_distribution.p12
```

上記の２つめのコマンドを入力すると下記のようにパスワードを要求されるので、適宜入力します。
（よもや ID / PASS のセキュリティは終わっている認識なので、ウチらはあえてパスワードなしで運用してます。何かあっても、最悪、証明書を無効化すれば良いので。[^2]）

```sh
Enter Export Password:
Verifying - Enter Export Password:
```

[^2]: まぁ、 ```Apple Developer``` へのログインが 2FA なのでより保護されている場所で対応する方針なんだけど、 Appleは　SMS認証や　```RFC6238```　みたいな一般的なトークン認証をサポートしていない。　Appleはいつでも ```Think different```　なヤツです。

### 6. p12 ファイルを ```キーチェーン``` に登録

p12 ファイルをダブルクリックすればOKです。
p12 ファイル生成時にパスワードを設定した場合、ここでパスワードを聞かれます。


### 7. ちゃんとバックアップ

大雑把な役割を含めてリスト化したので、どっかにバックアップを取っておきましょう。

|　ファイル名　|　種類 | 役目 |
|--|--|--|
|private.key|秘密鍵|ローカル側を証明するための鍵（ペアとなる公開鍵も含まれます。中身はPEM形式）|
|adc.csr|CSR|Appleさんに証明書を作ってもらうための自己紹介文（秘密鍵で暗号化して、公開鍵を自己紹介文と一緒にファイルに納めます）|
|ios_xxx.cer|証明書|Appleさんから発行された証明書 [^3] （納税者のみに与えられた権利です）|
|ios_xxx.pem|証明書|p12ファイルを生成するためにcerからエンコーディングを変換したもの|
|ios_xxx.p12|証明書＋秘密鍵|こいつを ```キーチェーン``` に登録|

※ ```xxx```　は　```development``` または ```distribution```　

[^3]: ```openssl``` で一連の作業を行う場合、　```ios_xxx.cer``` を ```キーチェーン```　に登録しただけではダメです。 ```Xcode``` ではビルドの後半で署名を行う際のですが、 ```ios_xxx.cer``` の要求元（つまり「あなた」）の秘密鍵（つまり ```private.key``` ）が必要となるためです。 そこで、 [「4. p12 ファイルを作成」](#4-p12-ファイルを作成)で 証明書と秘密鍵をペアにした p12 ファイルを生成し、これを ```キーチェーン```　に登録する流れになります。余談だがこの ```CER``` はエンコーディング形式で、X509形式を ```CER``` エンコーディングしているものです。