はじめに
こんにちは、iOSアプリ開発グループの神山です。
iOSアプリを開発、公開していく上で、証明書は必ず必要になってくるものになります。
証明書に関する有用な記事はたくさんあるのですが、自分がなかなか理解できずに全体的なイメージを掴めずにいました。
そこで、自分自身は証明書に関する概要をイラスト化することで理解を深めることができたため、今回はイラストを中心にご紹介いたします。
全体像
まずは証明書に関する全体像をイラストにしてみました。イラストはこちらの記事を参考に作成いたしました。
イラストの中に1~10の番号を割り振っており、1から順番に何を行なっているかの詳細を確認していきます。

概要詳細
0 データの暗号化 1 秘密鍵と公開鍵の作成 2 CSR(証明書署名要求)作成 3 証明書作成 4 証明書登録 5 appid登録 6 Device登録 7 プロビジョニングプロファイル登録(Apple Developer Center) 8 プロビジョニングプロファイル登録(ローカル) 9 ビルド設定 10 ビルドとアーカイブ 11 豆知識(Tips)
0.データの暗号化
証明書を知る上での予備知識として
1.秘密鍵・公開鍵の作成の前に、データの暗号化について取り上げたいと思います。もう既に大体は理解できている、とりあえず証明書の流れを知りたい方は1.秘密鍵と公開鍵の作成にお進みください。
データは暗号化せずにそのまま渡そうとすると、悪意のある第三者からデータを盗み見される可能性があります。

これを防ぐために必要なことがデータの暗号化です。
データを暗号化することで、受け取った側は暗号化されたデータを元のデータに戻す復号をしない限りは確認することができません。そのため、第三者から盗み見されたとしても中身が分からないようにすることができます。

では、データを暗号化・復号するために必要なものは何になるのでしょうか。
これが「鍵」になります。
鍵を用いて暗号化する方法は、暗号化と復号に同じ鍵を使う「共通鍵暗号方式」と、別々の鍵を用いる「公開鍵暗号方式」に分けられます。
共通鍵暗号方式
共通鍵暗号方式は暗号化と復号に同じ鍵を用いる暗号方式です。

第三者から盗み見されたとしても、暗号化されたデータのため、元のデータを確認することはできません。
しかし、共通鍵暗号方式には問題点もあります。
それが、データを受け取る側が共通鍵を持っておらず、送る側が共通鍵も渡す場合に、第三者が盗み見した時にその共通鍵を使ってデータを復号できてしまう点です。

このように、共通鍵暗号方式では、共通鍵を安全に伝える方法が必要になります(鍵配送問題)。
解決方法の一つとしてあるのが、公開鍵暗号方式です。
公開鍵暗号方式
公開鍵暗号方式は暗号化と復号に異なる鍵を用いる暗号方式です。
暗号化に使う鍵を「公開鍵」、復号に使う鍵を「秘密鍵」と呼びます。

受け取る側が送る側に対して事前に公開鍵を送っておき、その公開鍵を使ってデータを暗号化します。暗号化されたデータは秘密鍵のみが復号できるようになっています。
公開鍵と暗号化されたデータに関しては第三者から盗み見される可能性がありますが、暗号化されたデータを復号できるのは秘密鍵のみなので、元のデータに復号することができません。
このように、公開鍵暗号方式は共通鍵暗号方式の鍵配送問題を解決することができますが、一方で別の問題が発生します。
それが、公開鍵の信頼性に関する問題です。

公開鍵は作成者などに関する情報を持たないため、受け取る側が公開鍵を渡す際に、もし第三者が自身で作成した公開鍵とすり替えても、送る側が受け取る側からの公開鍵なのか、第三者にすり替えられた公開鍵なのかを判断することができません。
解決方法としてあるのが、後述する「デジタル証明書」の仕組みの利用です。
iOSにおいては、証明書が公開鍵暗号方式、デジタル証明書、デジタル署名といったものを組み合わせて開発者情報の特定、開発者が署名してからアプリが改変されていないことの検証をしています。
ということで、全体像の1から順番に確認していきます。
1.秘密鍵と公開鍵の作成
秘密鍵・公開鍵は
2.CSR(証明書署名要求)作成の際に自動的に作成されるため、開発者が何かをする必要はありません。ここでは、秘密鍵・公開鍵がどこで使用されるのかについて確認してみます。
秘密鍵・公開鍵はコード署名の中で使用されます。コード署名とは、iOSにおいては以下のようなことを可能にするための仕組みです。
- iOSがそのアプリの発行元を識別できる
- iOSがそのアプリが最後に署名してから改変されていないことを確認できる
具体的に実現したいことは以下の2点になります。
- アプリケーションコードが改ざんされていないこと
- 特定のユーザによって署名されていること
アプリケーションコードが改ざんされていないこと
アプリケーションコードが改ざんされていないかどうかを確認するにはハッシュ関数を使います。
ハッシュ関数とは、与えられたデータを、固定長の不規則な値に変換する関数のことを指します。

ハッシュ関数は特徴として同じ入力なら出力も必ず同じになる、ハッシュ値から元のデータを逆算することはできないなどの特徴を持っています。

アプリケーションコードもハッシュ関数の特徴を用いて、改ざんされていないことを確認することができます。
開発者はアプリケーションコードをiOSに渡す際にアプリケーションコードを特定のハッシュ関数でハッシュ化します。そして、ハッシュ化前の元のアプリケーションコードとハッシュ化後のハッシュ値の両方をiOSに渡します。
受け取る側のiOSはハッシュ化前のコードを、開発者が利用した特定のハッシュ関数と同じハッシュ関数でアプリケーションコードをハッシュ化します。こうして得られたハッシュ値が開発者から送られてきたハッシュ値と一致した場合、ハッシュ化前のコードは改ざんされていないということが分かります。

しかし、これはハッシュ値自体が改ざんされていないことが前提となります。データが改ざんされた後に、ハッシュ値も計算し直されて送られてきた場合、改ざんに気づくことができないためです。逆に、このハッシュ値が改ざんされていないことが保証されていれば、ハッシュ化前のアプリケーションコードが改ざんされていないことも同時に保証できることになります。

特定のユーザによって署名されていること
ハッシュ関数で計算されたハッシュ値は改ざんされていないことを前提としていると説明しましたが、改ざんされていないことを保証するためにデジタル署名を利用します。
デジタル署名は改ざんの検出を検知できるだけでなく、送信者を特定できる特徴も持っています。

また、実際にはデータを直接暗号化するのではなく、データのハッシュ値を計算してから、そのハッシュ値を暗号化して署名に用いるため、第三者から盗み見されたとしても検出することができます。

デジタル署名で改ざんの検出、送信者の特定をすることができましたが、1つ問題もあります。
それが、公開鍵暗号方式と同じく、公開鍵の信頼性の問題です。公開鍵には作成者の情報が一切含まれていないため、第三者が送信者をなりすますことができてしまいます。

そこで、公開鍵の正当性を保証できる仕組みがデジタル証明書になります。
デジタル証明書は、認証局(CA: Certifcation Authority)を通して、公開鍵に自身の情報を含めたものになります。

そのため、公開鍵を送る際には、直接公開鍵を送る代わりにデジタル証明書を送ります。

第三者がなりすまして自身の公開鍵を認証局に登録しようとしても、なりすますための相手の個人情報を持っていないため証明書を発行することができません。

コード署名においてもデジタル証明書が使われ、最終的には以下のような流れになります。

デジタル署名で暗号化する際に使用する秘密鍵は、秘密鍵を保有する署名者しか行うことができません。そのため、結果としてコード署名で実現したい「アプリケーションが改ざんされていないこと」、「特定のユーザによって署名されていること」を満たせることになります。
2.CSR(証明書署名要求)作成
CSRは証明書署名リクエストで、認証局(Apple)に自身の開発者情報を送るための事前準備になります。
CSR作成時に秘密鍵・公開鍵のペアが作成され、ローカルマシン内のキーチェーンに保存されます。
さらに、公開鍵は自身の開発者情報と共にCSRに含まれます。
※ CSR → .certSigningRequestファイル形式で作成されます

CSR作成方法
- キーチェンアクセス → 証明書アシスタント → 認証局に証明書を要求

証明書情報を入力、ローカルに保存

鍵ペア情報入力(2048ビット、RSA選択)

3.証明書作成
2.CSR(証明書署名要求)作成で準備したCSRに対して、認証局のデジタル署名を付与したものになります。いわゆる前述で紹介したデジタル証明書と同等のものになります。
※ 証明書 → .cerファイル形式で作成されます

神山義仁
iOSエンジニアです。