DRM開発入門 (1) 公開鍵暗号と共通鍵暗号とハイブリッド暗号

Published: Wed May 01 2019

Category: Web, Security

私はソフトウェアを開発するうちにDRM(ライセンス認証)の実装に興味を持つようになりましたが、その開発は困難を極めるものでした。

理由としては、日本語のリソースが殆ど無いことが一番にあげられるかと思います。

このシリーズでは、DRMの開発(主にロジック)について、出来得る限り説明していく予定です。

第一回は公開鍵暗号と共通鍵暗号について説明していきます。

この記事は私の理解に基づいています。

業務で使用する場合は、適切なセキュリティの専門家に相談する事をお勧めします。

暗号化とは

暗号化とは具体的に何なのでしょうか?

例えば以下のような文章を、AさんからBさんに、友達伝いで伝えるとします。

Why don't we go out for dinner sometime?

Aさんは友達にはこの内容を知られたくありません。

この場合、何らかの方法-具体的にはAさんとBさんしか知り得ない方法-で文章を暗号にして、それを解読できるようにする必要があります。

単純な暗号化のひとつに、シーザー暗号というものがあります。

これは英語のEをBに、DをAに、という風に、決められた数だけスライドさせていく、という暗号化方式です。

例として先程の文章を1文字ずつ次の文字にずらすと、以下のような文章になります。

XIZ EPO'U XF HP PVU GPS EJOOFS TPNFUJNF?

これが暗号化です。

この例は単純ですが、例えばAはCに、CはXに、というように暗号化の方式を複雑にすることで、ある程度の強度を保つことが可能です。

共通鍵暗号とは

共通鍵暗号 (対称暗号) とは、 暗号化する側と復号化する側が同じ鍵を使用する 暗号化方式です。

AESやDESなどが代表として挙げられます。

また、先程のシーザー暗号も共通鍵方式です。

AES暗号方式では、平文、暗号文、鍵に加え、saltとivというものが登場します。

これについて初心者には理解が難しいため、ここで説明します。

salt(ソルト)は鍵をハッシュ化する際に使用します。 この値はユーザーごとに固有である必要があります。 また、このsaltは復号化時に必要ですが、秘密である必要はありません。

iv(initial vector/初期化ベクトル)は、暗号文を毎回ランダムにするために使用します。 そのため、iv自体はランダムである必要があります。

同じ鍵を使用するため、計算コストが低いという特徴がありますが、トレードオフとして、鍵の交換を安全に行う必要がある、という点は留意しなければなりません。

この鍵の交換にはディフィー・ヘルマン鍵共有が使用されることが多いです。LINEのLetter Sealingにもこの技術が使用されています。 これについては非常に複雑で、私の理解も追いついていないため、LINE Engineeringのブログを閲覧することをおすすめします。

要するに鍵を盗まれてしまうと暗号化も復号化も出来てしまうということが大きなデメリットですね。

公開鍵暗号とは

公開鍵暗号 (非対称暗号) とは、 暗号化する側と復号化する側が別々の鍵を使用する 暗号化方式です。

RSAが代表として挙げられます。

RSA Encryption

名前の通り、公開鍵は基本的に暗号化のみに使用されるもので、第三者に盗まれたとしてもそれを利用して復号化することはできません。

対して秘密鍵は、受信者のみが所持するもので、公開鍵とは全く別の鍵です。これは基本的に復号化のみに使用されます。

公開鍵の作成には秘密鍵が必要です。 言い換えると、秘密鍵があれば公開鍵をいくらでも作成できてしまいます。 そのためクライアント側で公開鍵を使用し暗号化、サーバー側で秘密鍵を使用し復号化する、というのが一般的な流れとなっています。

後の章で触れますが、リバースエンジニアリングという技術でソフトウェア内部のテキストとロジックを見ることや改変することが可能です。

そのため、秘密鍵をクライアントサイドに渡して復号化、という流れには大きなセキュリティリスクを伴います。

それを解決するのがハイブリッド暗号です。

ハイブリッド暗号

ハイブリッド暗号とは、その名の通り 共通鍵暗号と公開鍵暗号を組み合わせた 暗号化方式です。

HTTPSのSSL/TLSといえば聞き馴染みはあるでしょうか。 -> 誤解でした。詳しくは@angel_p_57さんの SSL/TLSの基本 を参照してください。

この方式では以下のようなフローで暗号文と鍵の送信を行います。

  1. 送信者が共通鍵Aを作成
  2. 平文をその共通鍵Aで暗号化 (=暗号文A)
  3. 共通鍵を事前に用意していた公開鍵で暗号化 (=暗号鍵A)
  4. 暗号文Aと暗号鍵Aを受信者に送信

暗号の受信者のフローは以下の通りです。

  1. 受信者は、送信されてきた暗号鍵Aを秘密鍵を使用して復号化
  2. その復号化された鍵を使用して、送信されてきた暗号文Aを復号化

このハイブリッド暗号にはいくつかの利点がありますが、最も大きい点が2つあります。

第一に 送信者が鍵を作成するということ 、次に その鍵を公開鍵で暗号化する という点です。

この方式を採用することによって、比較的安全に鍵の交換が可能です。

終わりに

この章では暗号化方式について解説しました。

適切な暗号化を破ることは非常に難しいですし、現代の一般的なコンピュータでは解析に時間がかかります。

それでも留意していただきたいことは、暗号化を破るよりその前後のロジックを破る方が遥かに簡単であるという点です。

これについては次章以降で説明します。