わかる! OpenPGP 暗号

OpenPGP は秘密データを当事者以外の第3者から守るための暗号スイート(cipher suite)です。 この記事では OpenPGP で使われている暗号技術について解説します。

  1. わかる! OpenPGP 暗号
    1. そもそも「暗号」とは
    2. 「暗号」で何ができるのか
    3. 共通鍵暗号(Symmetric-Key Cryptography)
    4. 公開鍵暗号(Public-Key Cryptography)
    5. 暗号周辺の技術
    6. OpenPGP における暗号化手順
    7. OpenPGP 鍵の構成
    8. 公開鍵基盤(Public Key Infrastructure)としての OpenPGP
  2. 暗号に関する雑多な話
    1. GnuPG の使い方
    2. GnuPG 以外の OpenPGP 実装
    3. 安全な鍵長について
    4. パスフレーズ(Passphrase)の長さについて
    5. X.509 と OpenPGP
  3. 参考文献
  4. フィードバック

そもそも「暗号」とは

そもそも「暗号」とはなんでしょう。 暗号と呼ばれているものには様々なものがありますが,セキュリティの世界でいう「暗号」は専ら数学的な手法を使ったものです。

\[ S' = F(S,K_1) \label{eq:enc} \] \[ S = F^{-1}(S',K_2) \label{eq:dec} \]

この2つの式が成り立つ仕組みを「暗号(cipher, cryptography)」と呼びます。 また,式 \eqref{eq:enc} を「暗号化(encryption)」,式 \eqref{eq:dec} を「復号(decryption)」と呼びます。

暗号化では元のデータ $S$ に対し関数 $F$ をパラメータ $K_1$ と共にあてはめ,新たなデータ $S'$ を生成します(元のデータ $S$ を「平文(plain text)」,新たなデータ $S'$ を「暗号文(cipher text)」と呼びます)。 暗号文 $S'$ から平文 $S$ が推測(解読)できないのが特徴です。

復号では暗号文 $S'$ に対し関数 $F^{-1}$ をパラメータ $K_2$ と共にあてはめ,平文 $S$ を復元します。

関数 $F$ および $F^{-1}$ のセットを「暗号方式」または単に「アルゴリズム(algorithm)」と呼び,パラメータ $K_1$ および $K_2$ を「鍵(key)」と呼びます。 よく出来た暗号は,その暗号強度(暗号の破れにくさ)が鍵の「鍵長(key size)」に依存するように設計されています。 コンピュータシステムにおいてはアルゴリズムはプログラムコードとして記述されるため秘密にできません。 一方,鍵はプログラムとは独立のデータなので,鍵さえ知られなければ平文 $S$ を安全に管理することができます。

このように,データ・アルゴリズム・鍵の3つの要素を組み合わせてデータを秘匿する技術が「暗号」なのです。

(「暗号」に近い技術として「隠蔽」があります。 これは対象のデータを一定の手順で別のデータに潜ませる技術です(逆手順で対象データを抽出します)。 「隠蔽」の具体例としてはステガノグラフィ(steganography)あるいは電子透かし(digital watermark)があります)

「暗号」で何ができるのか

この「暗号」を使って何ができるのでしょうか。 OpenPGP では「暗号」を使って以下の機能を達成します。

機密性(Confidentiality)
対象となるデータ(平文)が第3者に知られないよう秘匿します。これは「暗号」の基本的な機能ですね。
完全性(Integrity)
データ(平文または暗号文)が第3者によって改竄されていないか検知します。これには「暗号」の応用である「電子署名(digital signature)」という仕組みを使います。(電子署名については後ほど解説します)
認証(Authentication)
当事者同士でデータをやりとりする際に,なりすまし等を防止するため,正しい相手であるか確認(認証)する必要があります。認証機能の一部は電子署名(後述)を使って行いますが,本当に正しい(信頼できる)相手であるか確認するための仕組み「基盤(infrastructure)」が必要です。(この「基盤」についても後ほど解説します)
否認防止(Non-repudiation)
「否認防止」とはデータをやりとりした際に「データを送った」という事実を送信側が否定出来ないようにすることを言います。これは見落とされがちですが重要な機能です。「否認防止」は「完全性」と「認証」を達成する事で実現できます。

(最近のメッセージング・アプリでは OTR(Off-the-Recording)機能を持ったものがあります。 OTR の特徴のひとつが「否認可能(Deniability)」です。 やりとりした過去のメッセージについて送信元を証明できなくする機能で,通信の匿名性を補強する機能として「スノーデン以後」の現代において注目されています。 OpenPGP 暗号は「否認可能」ではありません)

ではこれから OpenPGP でどのような暗号技術が用いられているか見ていくことにしましょう。

共通鍵暗号(Symmetric-Key Cryptography)

先ほどの式 \eqref{eq:enc} \eqref{eq:dec} を思い出して下さい。 2つの式にある鍵 $K_1$ および $K_2$ が同じであるアルゴリズムを「共通鍵暗号(symmetric-key cryptography)」といいます(対称暗号(symmetric cryptography),秘密鍵暗号(secret key cryptography)と呼ばれることもあります)。 多くの場合,復号のアルゴリズム $F^{-1}$ が暗号化のアルゴリズム $F$ の逆手順になっているのも特徴です。

共通鍵暗号の利点はアルゴリズムがコンパクトで高速な点にあります。 また暗号文のデータサイズが(平文と比べて)あまり変わらないのも利点です。

欠点は,暗号化と復号で同じ鍵を使うため当事者間で鍵を共有しなければならないことです。 これは「鍵配送問題」と呼ばれ長年の懸案になっていました。

さらに運用上の問題点として,共通鍵暗号は1対1で使われる暗号であるため,大勢が一度に運用する場合に,必要となる鍵の数が膨大になり過ぎる,という点が挙げられます。($n$ 人が共通鍵暗号でやり取りするには一番単純な場合で $n(n-1)/2$ 個の鍵を管理する必要があります)

OpenPGP で使用可能な共通鍵暗号アルゴリズム

OpenPGP で利用可能な共通鍵暗号アルゴリズムは次のとおりです。

IDアルゴリズム鍵長ブロック長参考文献
1 IDEA 128 64 "IDEA International Data Encryption Algorithm"
2 TripleDES (3TDEA) 168 (112 bits of strength) 64 SP800-67
3 CAST5 128 64 RFC2144
4 Blowfish 128 64 "Description of a New Variable-Length Key, 64-Bit Block Cipher (Blowfish)"
5 Reserved -- --  
6 Reserved -- --  
7 AES with 128-bit key 128 128 FIPS PUB 197
8 AES with 192-bit key 192 128 FIPS PUB 197
9 AES with 256-bit key 256 128 FIPS PUB 197
10 Twofish with 256-bit key 256 128 "The Twofish Encryption Algorithm"
11 Camellia with 128-bit key 128 128 RFC3713
12 Camellia with 192-bit key 192 128 RFC3713
13 Camellia with 256-bit key 256 128 RFC3713
OpenPGP で使用可能な共通鍵暗号アルゴリズム一覧

(OpenPGP では暗号モードに CFB(Cipher Feedback) mode (の変型; RFC4880: 13.9. OpenPGP CFB Mode)を使用します。

Camellia 218/192/256 は RFC5581 で追加されました)

公開鍵暗号(Public-Key Cryptography)

前述したように,共通鍵暗号は安全に鍵を管理・配送するのに膨大なコストがかかるため,政府や軍あるいは大企業以外には扱いかねるものでした。 この問題を解消したのが1970年代に登場した「公開鍵暗号(public-key cryptography)」です。

再び式 \eqref{eq:enc} \eqref{eq:dec} を思い出して下さい。 暗号化に使う鍵 $K_1$ と復号に使う鍵 $K_2$ が異なるもので,かつ鍵 $K_1$ から鍵 $K_2$ が推測できない関数 $F$ / $F^{-1}$ が存在すれば,暗号化に使う鍵 $K_1$ は秘密にする必要がなくなります(公開可能な鍵 $K_1$ を「公開鍵(public key)」といい,秘密の鍵 $K_2$ を「秘密鍵(private key or secret key)」といいます)。 このような関数は落し戸関数(trap door function)あるいは一方向関数(one-way function)と呼ばれています。 具体的には離散対数や素因数分解などの数学的な特徴を利用したものです。

公開鍵暗号の利点は鍵配送のコストを低く抑えることができることです。 また秘密鍵を誰とも共有する必要が無いため,ひとつの鍵(公開鍵と秘密鍵の組み合わせ)で複数の相手とやりとりが可能になるのも利点です。 一方で公開鍵暗号は鍵長が巨大になるものが多く,処理速度も遅く,暗号文も巨大になる傾向(概ね平文の倍のサイズ)があります。

電子署名(Digital Signature)への応用

再び再び,式 \eqref{eq:enc} \eqref{eq:dec} を思い出して下さい。 もし暗号化に使う鍵 $K_1$ を秘密鍵とし,復号に使う鍵 $K_2$ を公開鍵にできるとすると,どうなるでしょう。 暗号化できるのは秘密鍵を持っている人のみなので,暗号文 $S'$ を公開鍵で復号した結果と実際の平文 $S$ を比較して全く同じであれば,暗号化を行ったのが秘密鍵を持っている本人であると証明できます。 これが「電子署名(digital signature)」の基本的な考え方です。

電子署名を用いることでデータの「完全性」を証明できます。 また電子署名は「認証」にも用いることができます(電子署名だけではダメですが)。 「完全性」と「認証」が達成できれば「否認防止」も達成できます。

OpenPGP で使用可能な公開鍵暗号アルゴリズム

OpenPGP で利用可能な公開鍵暗号アルゴリズムは次のとおりです。

IDアルゴリズム参考文献
1 RSA (Encrypt or Sign) "PKCS #1: RSA Cryptography Standard", RFC3447
2 RSA Encrypt-Only "PKCS #1: RSA Cryptography Standard", RFC3447
3 RSA Sign-Only "PKCS #1: RSA Cryptography Standard", RFC3447
16 Elgamal (Encrypt-Only) Taher El Gamal A public key cryptosystem and a signature scheme based on discrete logarithms
17 DSA (Digital Signature Algorithm) FIPS PUB 186-4
18 ECDH SP800-56A Revision 1
19 ECDSA FIPS PUB 186-4
20 Reserved (formerly Elgamal Encrypt or Sign)
21 Reserved for Diffie-Hellman ANSI X9.42, as defined for IETF-S/MIME
22 EdDSA High-speed high-security signatures
OpenPGP で使用可能な公開鍵暗号アルゴリズム一覧

(DSA および ECDSA は署名専用のアルゴリズムです。 また Diffie-Hellman はリモートとの通信時にリアルタイムで安全に鍵を交換するためのアルゴリズムです。 SSL/TLS や ssh などでよく用いられますが OpenPGP では今のところ用いられません。

ECDH および ECDSA は RFC6637 で追加されました。 EdDSA は現在ドラフト段階です)

暗号周辺の技術

暗号そのものではないですが,暗号に不可欠な要素技術を以下に紹介します。

メッセージ要約(Message Digest)

公開鍵暗号(電子署名も含む)の欠点は

  • 処理に時間がかかること
  • 平文よりも暗号文の方が大きくなる(概ね倍のサイズ)こと

です。 したがって,平文そのものを使って電子署名を行うのは効率的ではありません。 そこで平文を短い数値列に「要約」することが考えられました。 これが「メッセージ要約(message digest)」と呼ばれるものです。

メッセージ要約として使われるアルゴリズムは「一方向ハッシュ関数(one-way hash function)」と呼ばれています。 一方向ハッシュ関数には次の機能が要求されます。

  • ハッシュ値から元のデータが復元できないこと
  • 複数データのハッシュ値が衝突しないこと

OpenPGP で利用可能なアルゴリズムは次のとおりです。

IDアルゴリズム参考文献
1 MD5 RFC1321
2 SHA-1 FIPS PUB 186-2
3 RIPE-MD/160 "The hash function RIPEMD-160"
4 Reserved  
5 Reserved  
6 Reserved  
7 Reserved  
8 SHA256 FIPS PUB 180-4
9 SHA384 FIPS PUB 180-4
10 SHA512 FIPS PUB 180-4
11 SHA224 FIPS PUB 180-4
OpenPGP で使用可能な一方向ハッシュ関数一覧

S2K(String-to-Key)

S2K(string-to-key)はパスフレーズ(passphrase)などから共通鍵暗号用の鍵を生成する際に使われるアルゴリズムです。

IDS2K タイプ
1 Salted S2K
2 Reserved value
3 Iterated and Salted S2K
OpenPGP で使用可能な S2K アルゴリズム一覧

擬似乱数生成

充分に secure な乱数の生成はとても重要な技術要素です。 OpenPGP では RFC4086 を参照し擬似乱数生成を行います。

OpenPGP における暗号化手順

ここからは OpenPGP でどのように暗号化・復号が行われているのか見ていくことにしましょう。

その前に,いったん用語を整理しておきます。

平文(Plain Text)
暗号化する前のデータを指します。テキストとは限らずバイナリデータを含めてこう呼びます。
暗号文(Cipher Text)/dt>
平文を暗号化したデータを指します。通常はバイナリデータ(またはバイナリをテキスト展開したデータ)です。
メッセージ(Message)
やりとりする平文を「メッセージ」を呼ぶことがあります。これは OpenPGP 特有の言い回しで, OpenPGP の前身である PGP(Pretty Good Privacy)が主に電子メールの暗号化に利用されていたことに由来しています。また元のメッセージ(平文)に対する暗号文を「暗号化メッセージ(encrypted message)」と呼ぶことがあります。
送信者(Sender)
暗号化メッセージの送り手を指します。メッセージを暗号化するのも送信者です。
受信者(Recipient)
暗号化メッセージの受け手を指します(「受取人」という場合もあります)。受信者によって暗号化メッセージは復号されます。
共通鍵暗号(Symmetric-Key Cryptography)
暗号化と復号に同じ鍵を用いるアルゴリズムの総称です。コンパクトで高速なのが利点ですが,鍵の管理コストが高くなるのが欠点です。
公開鍵暗号(Public-Key Cryptography)
暗号化と復号に異なる鍵を用いるアルゴリズムの総称です。暗号化用の鍵を公開できるため鍵の管理コストを抑えられるのが利点ですが,処理が遅く暗号化メッセージが元のメッセージよりかなり大きくなるのが欠点です。
電子署名(Digital Signature)
公開鍵暗号の一種ですが暗号化用の鍵を秘密鍵とし復号用の鍵を公開します。この機能によりメッセージの完全性(integrity)を担保します。利点・欠点は公開鍵暗号と同じです。

アルゴリズムとして共通鍵暗号と公開鍵暗号を挙げましたが,それぞれ利点と欠点があります。 そこで OpenPGP では両者の利点を上手く組み合わせた「ハイブリッド暗号」を用います。

ハイブリッド暗号(Hybrid Cryptography)

コンパクトで高速な共通鍵暗号,鍵を安全に管理できる公開鍵暗号,両者の利点を組み合わせた暗号化・復号の手順を「ハイブリッド暗号(hybrid cryptography)」と呼びます。

まず,ハイブリッド暗号の暗号化の手順を以下に示します。

Hybrid Encription
ハイブリッド暗号による暗号化手順(参考:結城浩著『新板暗号技術入門』)

メッセージを暗号化するための鍵を「セッション鍵(session key)」と言います。 セッション鍵は暗号化の度ごとに異なる鍵を擬似乱数生成器で生成します。 セッション鍵は受信者の公開鍵で暗号化します。 公開鍵暗号は処理が重く暗号文が大きくなるのが欠点ですが,セッション鍵は共通鍵暗号用の鍵で,鍵長の最大はせいぜい $512\,\mathrm{bits}$ ほどなので問題になりません。

一方,ハイブリッド暗号の復号は暗号化の逆手順で,以下のとおりになっています。

Hybrid Decryption
ハイブリッド暗号による復号手順(参考:結城浩著『新板暗号技術入門』)

セッション鍵の復号には受信者の秘密鍵を用います。 秘密鍵は受信者しか持っていないので,セッション鍵は受信者しか復号できません。 セッション鍵が復号できない限り暗号化メッセージも復号できません。

このようにしてメッセージの「機密性(confidentiality)」を保ちます。

鍵への電子署名

公開鍵は秘密情報ではないので第3者に知られても構いませんが,鍵配送の過程で改竄やなりすましを受ける可能性があります。

そこで鍵に対して受信者(鍵の持ち主)または送信者(公開鍵の使用者)が電子署名を行うことによって,改竄を防ぎなりすましのリスクを下げます。 (詳しくは後述の「公開鍵基盤」の節を参照して下さい)

OpenPGP 鍵の構成

OpenPGP 鍵は主に以下の「パケット(packet)」で構成されています。

  • 公開鍵パケット(Public-Key Packet)
  • 公開サブ鍵パケット(Public-Subkey Packet)
  • 秘密鍵パケット(Secret-Key Packet)
  • 秘密サブ鍵パケット(Secret-Subkey Packet)
  • ユーザ ID パケット(User ID Packet)
  • 署名パケット(Signiture Packet)

以降,1つづつ見ていくことにしましょう

公開鍵パケット/公開サブ鍵パケット(Public-Key Packet / Public-Subkey Packet)

公開鍵は1個の公開鍵パケットと0個以上の公開サブ鍵パケットを持ち,それぞれ公開鍵情報を格納します。 公開鍵パケットは主に電子署名の検証に用います。 公開サブ鍵パケットは暗号化に用います。

(ほとんどのアルゴリズムでは暗号化用の鍵と電子署名用の鍵は別になっているため,公開鍵パケットは電子署名用,公開サブ鍵パケットは暗号化用で使い分けます。 更に電子署名専用の鍵も作成可能で,その場合は公開サブ鍵パケットを含みません。 ちなみに暗号化専用の鍵は作成できません)

秘密鍵パケット/秘密サブ鍵パケット(Secret-Key Packet / Secret-Subkey Packet)

秘密鍵は1個の秘密鍵パケットと0個以上の秘密サブ鍵パケットを持ち,それぞれ秘密鍵情報を暗号化した状態で格納します。 秘密鍵パケットは主に電子署名に用います。 秘密サブ鍵パケットは復号に用います。

秘密鍵情報の暗号化には共通鍵暗号を用います。 鍵はパスフレーズ(passphrase)から生成します(S2K)。

ユーザ ID パケット(User ID Packet)

公開鍵パケットまたは秘密鍵パケットに対して1個以上のユーザ ID パケットを持ちます(複数のユーザ ID が設定可能です)。 ユーザ ID は,通常はユーザの名前とメールアドレスが入りますが,内容に関して特に制約があるわけではありません。

署名パケット(Signiture Packet)

ユーザ ID パケットに対して0個以上の署名パケットを持ち,それぞれ電子署名情報を格納します。 また公開サブ鍵パケットおよび秘密サブ鍵パケットに対しても0個以上の署名パケットを持ちます。

(実際の OpenPGP 実装では,ユーザ ID パケットおよび公開/秘密サブ鍵パケットのそれぞれについて必ず自己署名(自分自身の電子署名用秘密鍵による電子署名)が付きます。 更に自己署名のない鍵は無効とされ使用することができないようになっています)

署名パケットには署名サブパケット(Signature Subpacket)によって以下の情報が付加されます。(主なもののみ挙げています)

  • 署名作成日時(signature creation time)
  • 鍵有効期間(key expiration time)
  • 共通鍵暗号アルゴリズム設定(preferred symmetric algorithms)
  • 発行者の鍵 ID(issuer key ID)
  • ハッシュアルゴリズムの設定(preferred hash algorithms)
  • 圧縮アルゴリズムの設定(preferred compression algorithms)
  • プライマリユーザ ID(primary user id)
  • 鍵フラグ(key flags)
  • 失効の理由(reason for revocation): 鍵の失効については後述します

OpenPGP 鍵の生成から失効まで

ここで OpenPGP の実装のひとつである GnuPG を使って鍵の生成を実際に行ってみます。

まずは鍵の生成から。 鍵の生成には --gen-key オプションを付けて実行します。

> gpg --gen-key
gpg (GnuPG) 1.4.18; Copyright (C) 2014 Free Software Foundation, Inc.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Please select what kind of key you want: (1) RSA and RSA (default) (2) DSA and Elgamal (3) DSA (sign only) (4) RSA (sign only) Your selection? 2 DSA keys may be between 1024 and 3072 bits long. What keysize do you want? (2048) 3072 Requested keysize is 3072 bits Please specify how long the key should be valid. 0 = key does not expire <n> = key expires in n days <n>w = key expires in n weeks <n>m = key expires in n months <n>y = key expires in n years Key is valid for? (0) 30 Key expires at 11/14/14 21:53:38 Is this correct? (y/N) y

You need a user ID to identify your key; the software constructs the user ID from the Real Name, Comment and Email Address in this form: “Heinrich Heine (Der Dichter) <heinrichh@duesseldorf.de>”

Real name: John Doe Email address: john@examle.com Comment: Demonstration You selected this USER-ID: “John Doe (Demonstration) <john@examle.com>”

Change (N)ame, (C)omment, (E)mail or (O)kay/(Q)uit? o You need a Passphrase to protect your secret key.

Enter passphrase:

この例では公開鍵暗号アルゴリズムに DSA and Elgamal を,鍵長を $3072\,\mathrm{bits}$ とし,有効期限を30日に,ユーザ ID を John Doe (Demonstration) <john@examle.com> としました。 最後にパスフレーズを入力すれば鍵を生成できます。 生成した公開鍵は以下のようになっています。

> gpg --fingerprint --fingerprint 0xCE59D5FA
gpg: using PGP trust model
pub   3072D/CE59D5FA 2014-10-15 [expires: 2014-11-14]
      Key fingerprint = 72E3 0B61 4831 3F49 BB20  418B AB5B 0C7F CE59 D5FA
uid                  John Doe (Demonstration) <john@examle.com>
sub   3072g/EAE9813D 2014-10-15 [expires: 2014-11-14]
      Key fingerprint = 9309 0D77 D525 115B 0880  0C12 3937 2D4D EAE9 813D

Key fingerprint(鍵指紋)は公開鍵パケットおよび公開サブ鍵パケットの SHA-1 ハッシュ値($160\,\mathrm{bits}$)です。 3072D/CE59D5FA は公開鍵パケットのアルゴリズム(前半: $3072\,\mathrm{bits}$ DSA であることを示す)と鍵 ID を示します。 鍵 ID は鍵指紋の下 $32\,\mathrm{bits}$ (または $64\,\mathrm{bits}$)の値で,鍵の識別子として用いられています。 3072g/EAE9813D は公開サブ鍵パケットのアルゴリズム(前半: $3072\,\mathrm{bits}$ Elgamal であることを示す)と鍵 ID を示します。

では,この公開鍵を更に pgpdump で詳しく見てみましょう。

> gpg -a --export 0xCE59D5FA | pgpdump
gpg: writing to stdout
Old: Public Key Packet(tag 6)(1198 bytes)
        Ver 4 - new
        Public key creation time - Wed Oct 15 21:55:47 東京 (標準時) 2014
        Pub alg - DSA Digital Signature Algorithm(pub 17)
        DSA p(3072 bits) - ...
        DSA q(256 bits) - ...
        DSA g(3071 bits) - ...
        DSA y(3071 bits) - ...
Old: User ID Packet(tag 13)(42 bytes)
        User ID - John Doe (Demonstration) <john@examle.com>
Old: Signature Packet(tag 2)(128 bytes)
        Ver 4 - new
        Sig type - Positive certification of a User ID and Public Key packet(0x13).
        Pub alg - DSA Digital Signature Algorithm(pub 17)
        Hash alg - SHA256(hash 8)
        Hashed Sub: signature creation time(sub 2)(4 bytes)
                Time - Wed Oct 15 21:55:47 東京 (標準時) 2014
        Hashed Sub: key flags(sub 27)(1 bytes)
                Flag - This key may be used to certify other keys
                Flag - This key may be used to sign data
        Hashed Sub: key expiration time(sub 9)(4 bytes)
                Time - Fri Nov 14 21:55:47 東京 (標準時) 2014
        Hashed Sub: preferred symmetric algorithms(sub 11)(5 bytes)
                Sym alg - AES with 256-bit key(sym 9)
                Sym alg - AES with 192-bit key(sym 8)
                Sym alg - AES with 128-bit key(sym 7)
                Sym alg - CAST5(sym 3)
                Sym alg - Triple-DES(sym 2)
        Hashed Sub: preferred hash algorithms(sub 21)(5 bytes)
                Hash alg - SHA256(hash 8)
                Hash alg - SHA1(hash 2)
                Hash alg - SHA384(hash 9)
                Hash alg - SHA512(hash 10)
                Hash alg - SHA224(hash 11)
        Hashed Sub: preferred compression algorithms(sub 22)(3 bytes)
                Comp alg - ZLIB <RFC1950>(comp 2)
                Comp alg - BZip2(comp 3)
                Comp alg - ZIP <RFC1951>(comp 1)
        Hashed Sub: features(sub 30)(1 bytes)
                Flag - Modification detection (packets 18 and 19)
        Hashed Sub: key server preferences(sub 23)(1 bytes)
                Flag - No-modify
        Sub: issuer key ID(sub 16)(8 bytes)
                Key ID - 0xAB5B0C7FCE59D5FA
        Hash left 2 bytes - e5 fb
        DSA r(256 bits) - ...
        DSA s(255 bits) - ...
                -> hash(DSA q bits)
Old: Public Subkey Packet(tag 14)(781 bytes)
        Ver 4 - new
        Public key creation time - Wed Oct 15 21:55:47 東京 (標準時) 2014
        Pub alg - ElGamal Encrypt-Only(pub 16)
        ElGamal p(3072 bits) - ...
        ElGamal g(3 bits) - ...
        ElGamal y(3072 bits) - ...
Old: Signature Packet(tag 2)(103 bytes)
        Ver 4 - new
        Sig type - Subkey Binding Signature(0x18).
        Pub alg - DSA Digital Signature Algorithm(pub 17)
        Hash alg - SHA256(hash 8)
        Hashed Sub: signature creation time(sub 2)(4 bytes)
                Time - Wed Oct 15 21:55:47 東京 (標準時) 2014
        Hashed Sub: key flags(sub 27)(1 bytes)
                Flag - This key may be used to encrypt communications
                Flag - This key may be used to encrypt storage
        Hashed Sub: key expiration time(sub 9)(4 bytes)
                Time - Fri Nov 14 21:55:47 東京 (標準時) 2014
        Sub: issuer key ID(sub 16)(8 bytes)
                Key ID - 0xAB5B0C7FCE59D5FA
        Hash left 2 bytes - a5 62
        DSA r(253 bits) - ...
        DSA s(254 bits) - ...
                -> hash(DSA q bits)

これまで述べたパケットの様子が見れると思います。

何らかの理由で鍵の有効期間より前に破棄しなければならない場合は,鍵の失効(revoke)手続きを行います。 まず失効証明書を作成します。 GnuPG の場合は --gen-revoke オプションで起動します。

> gpg -a -o john-revoke.asc --gen-revoke 0xCE59D5FA

sec 3072D/CE59D5FA 2014-10-15 John Doe (Demonstration) <john@examle.com>

Create a revocation certificate for this key? (y/N) y Please select the reason for the revocation: 0 = No reason specified 1 = Key has been compromised 2 = Key is superseded 3 = Key is no longer used Q = Cancel (Probably you want to select 1 here) Your decision? 3 Enter an optional description; end it with an empty line: > demonstration > Reason for revocation: Key is no longer used demonstration Is this okay? (y/N) y

You need a passphrase to unlock the secret key for user: “John Doe (Demonstration) <john@examle.com>” 3072-bit DSA key, ID CE59D5FA, created 2014-10-15

Enter passphrase:

gpg: writing to `john-revoke.asc’ gpg: DSA/SHA256 signature from: “CE59D5FA John Doe (Demonstration) <john@examle.com>” Revocation certificate created.

Please move it to a medium which you can hide away; if Mallory gets access to this certificate he can use it to make your key unusable. It is smart to print this certificate and store it away, just in case your media become unreadable. But have some caution: The print system of your machine might store the data and make it available to others!

ちなみにこの失効証明書の中身はこのようになっています。

> pgpdump john-revoke.asc
Old: Signature Packet(tag 2)(110 bytes)
        Ver 4 - new
        Sig type - Key revocation signature(0x20).
        Pub alg - DSA Digital Signature Algorithm(pub 17)
        Hash alg - SHA256(hash 8)
        Hashed Sub: signature creation time(sub 2)(4 bytes)
                Time - Wed Oct 15 22:50:14 東京 (標準時) 2014
        Hashed Sub: reason for revocation(sub 29)(14 bytes)
                Reason - Key is retired and no longer used
                Comment - demonstration
        Sub: issuer key ID(sub 16)(8 bytes)
                Key ID - 0xAB5B0C7FCE59D5FA
        Hash left 2 bytes - e7 ce
        DSA r(254 bits) - ...
        DSA s(255 bits) - ...
                -> hash(DSA q bits)

この失効証明書をインポートすることで目的の鍵を失効することができます。

> gpg --import john-revoke.asc
> gpg --fingerprint --fingerprint 0xCE59D5FA
gpg: using PGP trust model
pub   3072D/CE59D5FA 2014-10-15 [revoked: 2014-10-15]
      Key fingerprint = 72E3 0B61 4831 3F49 BB20  418B AB5B 0C7F CE59 D5FA
uid                  John Doe (Demonstration) <john@examle.com>
sub   3072g/EAE9813D 2014-10-15 [revoked: 2014-10-15]
      Key fingerprint = 9309 0D77 D525 115B 0880  0C12 3937 2D4D EAE9 813D

公開鍵基盤(Public Key Infrastructure)としての OpenPGP

これまで見てきたように公開鍵暗号を使えば鍵を安全に管理することができます。 また公開鍵暗号の応用である電子署名を使えばデータや鍵の改竄を防ぐことができます。 しかし,このままでは「なりすまし」を防ぐことができません。 「なりすまし」を防ぐためには,公開鍵が正しく本人のものであると証明する仕組みが必要です。 この仕組みのことを公開鍵基盤(PKI; Public Key Infrastructure)と呼びます。 電子署名と公開鍵基盤を組み合わせることで「認証(authentication)」が達成できます。

ここでは OpenPGP がどのようにして公開鍵を証明しているのか見ていくことにします。

OpenPGP における鍵の配送・交換

OpenPGP では公開鍵が本人のものであるかどうかを末端利用者(end user)同士が個人レベルで認証します。 OpenPGP では権威的に機能する CA(Certification Authority)は存在しません。 ではどのようにして公開鍵を認証しているのか,簡単な例で説明します。

ケース1:直接公開鍵を交換する場合

メッセージを交換したい2人のユーザ Alice と Bob を想定してみます。 交換したいメッセージは第3者には秘密にしておきたいのでメッセージを暗号化してやりとりすることにしました。 そのために,まずお互いの公開鍵を交換します。 この交換には,直接手渡しするか(改竄やなりすましのない)安全な通信経路を使う必要があります。

Hybrid Decryption
公開鍵の交換1(Alice と Bob)

Alice と Bob はそれぞれ相手の公開鍵に署名し送り返します(既に公開鍵の交換自体は成立しているので安全でない通信経路でも大丈夫です)。

Hybrid Decryption
公開鍵の交換2(Alice と Bob)

これでお互いにお互いの公開鍵を認証したことになります。

Hybrid Decryption
公開鍵の交換3(Alice と Bob)

ケース2:第3者の署名で公開鍵を認証する場合

Alice と Bob に加えて Chris ともメッセージを交換したいと考えます。 このとき既にAlice と Chris の間では公開鍵の交換と認証が完了しているとします。

Hybrid Decryption
公開鍵の交換4(Alice と Bob と Chris)

Bob と Chris の間でも公開鍵を交換したいのですが,お互い面識が無いため,安全に公開鍵を交換する方法がありません。 この場合でも,Chris の公開鍵には既に Alice の電子署名があるため, Bob は Chris の公開鍵を(Alice の電子署名を通じて)認証できます。 Bob の公開鍵も同様に(Alice の電子署名を通じて)認証できます。

Hybrid Decryption
公開鍵の交換5(Alice と Bob と Chris)

ケース3:鍵サーバ(Keyserver)を介して公開鍵を取得する場合

公開鍵を鍵サーバ(Keyserver)に預け,利用者と鍵サーバとの間で公開鍵(と電子署名)の状態を最新に保つことで,利用者間の鍵の交換と認証がスムーズになります。 これはメッセージをやりとりする関係者が多い場合に有効です。

Hybrid Decryption
公開鍵の交換6(Alice と Bob と Chris と鍵サーバ)

ただし,この場合でも認証を行うのはあくまでも利用者側です。 鍵サーバはアップロードされる公開鍵に対して何の保証もしません。

実際にインターネットではいくつかの鍵サーバが稼働しています。

鍵サーバ間は同期しているため,どの鍵サーからも同じ公開鍵を取得する事ができます。

OpenPGP の信用モデル(Trust Model)

先程述べたように, OpenPGP では公開鍵が本人のものであるかどうかを末端利用者(end user)同士が個人レベルで認証します。 取得した公開鍵を認証する際に電子署名を行うのですが,このとき公開鍵に対して以下の信用度(trust)を設定できます。

  • 未定義(undefined)
  • 未知(unknown)
  • 信用しない(untrusted)
  • ある程度信用する(marginal)
  • 完全に信用する(complete)
  • 絶対的に信用する(ultimate; 自分自身のみ)

公開鍵を認証する際は電子署名ごとの信用度をチェックし,最終的に鍵の有効性(validity; 改竄やなりすましがないこと)を以下のように判定されます(信用度と同じ名称なのでややこしいですが)。

  • 未定義(undefined)
  • 無効(untrusted)
  • 最低限有効(marginal)
  • 完全に有効(complete)

つまり,ある鍵に対して多くのユーザから高い信用度(「ある程度信用する」または「完全に信用する」)を集めるほど有効性も高くなるわけです。 このやり方であれば未知のユーザの公開鍵でも(鍵に付与される信用度を基に)判断することができます。

このように鍵に対する署名(および信用度)のネットワークによって有効性を判断するモデルを「信用の輪(web of trust)」と言います。 OpenPGP の公開鍵基盤はこの「信用の輪」がベースになっています。

(ここで言う「信用」は「あなたは人として信用できる」の信用ではなく,鍵に対して改竄やなりすましがなく適切に運用されているか否かという意味での信用です。 たとえ有名人の鍵であっても安全な方法で鍵を受け取っているのでなければ安易に信用すべきではありません。 一方,顔見知りから直接鍵を受け取ったなら改竄やなりすましは低いと判断できます)

暗号に関する雑多な話

GnuPG の使い方

代表的な OpenPGP 実装である GnuPG の使い方は --help オプションで起動すると分かります。

> gpg --help
gpg (GnuPG) 1.4.18
Copyright (C) 2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Home: ******** Supported algorithms: Pubkey: RSA, RSA-E, RSA-S, ELG-E, DSA Cipher: IDEA (S1), 3DES (S2), CAST5 (S3), BLOWFISH (S4), AES (S7), AES192 (S8), AES256 (S9), TWOFISH (S10), CAMELLIA128 (S11), CAMELLIA192 (S12), CAMELLIA256 (S13) Hash: MD5 (H1), SHA1 (H2), RIPEMD160 (H3), SHA256 (H8), SHA384 (H9), SHA512 (H10), SHA224 (H11) Compression: Uncompressed (Z0), ZIP (Z1), ZLIB (Z2), BZIP2 (Z3)

Syntax: gpg [options] [files] Sign, check, encrypt or decrypt Default operation depends on the input data

Commands:

-s, –sign [file] make a signature –clearsign [file] make a clear text signature -b, –detach-sign make a detached signature -e, –encrypt encrypt data -c, –symmetric encryption only with symmetric cipher -d, –decrypt decrypt data (default) –verify verify a signature –list-keys list keys –list-sigs list keys and signatures –check-sigs list and check key signatures –fingerprint list keys and fingerprints -K, –list-secret-keys list secret keys –gen-key generate a new key pair –delete-keys remove keys from the public keyring –delete-secret-keys remove keys from the secret keyring –sign-key sign a key –lsign-key sign a key locally –edit-key sign or edit a key –gen-revoke generate a revocation certificate –export export keys –send-keys export keys to a key server –recv-keys import keys from a key server –search-keys search for keys on a key server –refresh-keys update all keys from a keyserver –import import/merge keys –card-status print the card status –card-edit change data on a card –change-pin change a card’s PIN –update-trustdb update the trust database –print-md algo [files] print message digests

Options:

-a, –armor create ascii armored output -r, –recipient NAME encrypt for NAME -u, –local-user use this user-id to sign or decrypt -z N set compress level N (0 disables) –textmode use canonical text mode -o, –output use as output file -v, –verbose verbose -n, –dry-run do not make any changes -i, –interactive prompt before overwriting –openpgp use strict OpenPGP behavior –pgp2 generate PGP 2.x compatible messages

(See the man page for a complete listing of all commands and options)

Examples:

-se -r Bob [file] sign and encrypt for user Bob –clearsign [file] make a clear text signature –detach-sign [file] make a detached signature –list-keys [names] show keys –fingerprint [names] show fingerprints

Please report bugs to <gnupg-bugs@gnu.org>.

また GnuPG のサイトには詳しいマニュアルもあります。 (ただし英語です。古いバージョン(v1.2)でよろしければ日本語の翻訳ページがあります。基本的な機能は同じです)

GnuPG 以外の OpenPGP 実装

代表的な OpenPGP 実装は GnuPG ですが,他に様々な実装があります。 以下に代表的なものを紹介しましょう。

PGP

OpenPGP の基(RFC1991)となった製品で,今も OpenPGP 実装のひとつとして利用されています。 紆余曲折ありましたが,現在は Symantec 社の製品として販売されています。

APG / OpenKeychain

Android 向けの OpenPGP 実装です。

APG(Android Privacy Guard)は GnuPG から Android への fork だそうです。 更に APG から fork した OpenKeychain が登場していて,現在は OpenKeychain の方が活発なようです。

OpenKeychain は単独で利用できる他, K-9 MailConversations などのアプリと連携しています。

iPGMail

iOS 向けの OpenPGP 実装のようです。

安全な鍵長について

OpenPGP では様々な暗号が使われますが,運用する際には適切な鍵長を選ぶ必要があります。

まず暗号強度と実際の鍵長との比較があります。

Bits of
security
Symmetric key
algorithms
FFC
(e.g., DSA, D-H)
IFC
(e.g., RSA)
ECC
(e.g., ECDSA)
80 2TDEA $L=1024$
$N=160$
$k=1024$ $160 \le f \lt 224$
1123TDEA $L=2048$
$N=224$
$k=2048$ $224 \le f \lt 256$
128AES-128$L=3072$
$N=256$
$k=3072$ $256 \le f \lt 384$
192AES-192$L=7680$
$N=384$
$k=7680$ $384 \le f \lt 512$
256AES-256$L=15360$
$N=512$
$k=15360$$512 \le f$
Comparable strengths (via SP800-57 Part 1 (Revision 3) )

表のように共通鍵暗号と公開鍵暗号を組み合わせる際は,鍵長の組み合わせに注意して適切な長さを選択して下さい。 特定のアルゴリズムの鍵のみ極端に小さかったりするとそこがセキュリティの弱点になりますし,逆に大きすぎても処理に時間がかかるだけで意味がありません。

上の表の各暗号強度(bits of security)に対してどの程度の期間まで有効か纏めた表もあります。

Security Strength 2011 through 2013 2014 through 2030 2031 and Beyond
80 Applying Deprecated Disallowed
Processing Legacy use
112Applying AcceptableAcceptableDisallowed
Processing Legacy use
128 Applying/ProcessingAcceptable Acceptable Acceptable
192 Acceptable Acceptable Acceptable
256 Acceptable Acceptable Acceptable
Security-strength time frames (via SP800-57 Part 1 (Revision 3) )

この表によると2030年以降も Acceptable な(安全に使えると考えられる)暗号強度は $128\,\mathrm{bits}$ 以上のようです。 先ほどの表も合わせて考えると

  • DSA, ElGamal, RSA なら $3072\,\mathrm{bits}$ 以上
  • ECDSA なら $256\,\mathrm{bits}$ 以上
  • 共通鍵暗号なら AES-128 以上

が安全な鍵長と言えそうです。

パスフレーズ(Passphrase)の長さについて

パスフレーズ(passphrase)はパスワード(password)と似ていますが,以下の点が異なります。

  • 空白文字を含むすべての文字(制御文字は除く)を使うことができる
  • 文字数に制限がない

OpenPGP ではパスフレーズをコンピュータ内のいかなる場所にも格納しません(ただしパスフレーズの入力を代行する agent ツールはパスフレーズをメモリ内に一定期間キャッシュします)。 入力したパスフレーズは S2K アルゴリズムを使って鍵に変換します。 この鍵は秘密鍵の暗号化・復号またはメッセージを共通鍵暗号のみで暗号化・復号する際に用います。

パスフレーズにしろパスワードにしろ文字数が多いほど推測されにくいのですが,どの程度の長さが必要なのでしょうか。 これには IPA のドキュメントが参考になります。

この中にパスワードの解読されやすさが載っています。

利用する文字種類数と内訳 パスワード長
種類数 数字 文字 シンボル 4文字 8文字 12文字 16文字
10種0-9なし なし1円未満($2^{13.3}$)1円未満($2^{26.6}$) 約35円($2^{39.9}$) 約35万円($2^{53.2}$)
36種0-9a-z なし1円未満($2^{20.7}$)約100円($2^{41.4}$) 約1.65億円($2^{62.0}$) 約276兆円($2^{82.7}$)
62種0-9a-z
A-Z
なし1円未満($2^{23.8}$)約7,500円($2^{47.6}$)約1,120億円($2^{71.5}$)約165京円($2^{95.3}$)
94種0-9a-z
A-Z
! " # $ %
& ' ( ) =
~ | - ^ `
¥ { @ [
+ * ] ; :
} < > ? _
, . /
1円未満($2^{26.2}$)約21万円($2^{52.4}$) 約16.5兆円($2^{78.7}$) 約129,000京円($2^{104.9}$)
パスワード解読の想定コスト例(情報漏えいを防ぐためのモバイルデバイス等設定マニュアル 解説編 2.4.2.2項より)
利用できる文字種類すべてを完全にランダムに選択して作ったパスワードを一つ一つ調べる全数探索により1日で解読しようとした際にかかるおおまかな想定攻撃コストを示しています。ここでは、全数探索(暗号鍵の総数256)でDES10を1日で解読するためのコストを約250万円と仮定します。また、パスワードを1つ検査するのとDESの暗号鍵を1つ検査するコストは同じであるとし、パスワードを求めるのに必要な計算量(検査する個数)が半分になればコストも半分、2倍になればコストも2倍になるものとしています。
情報漏えいを防ぐためのモバイルデバイス等設定マニュアル 解説編 2.4.2.2項より

この値をそのまま鵜呑みにすることはできませんが,パスワードの文字数が多くなるほど(具体的には12文字以上で)格段に解読しにくくなっているのがわかると思います。 実際にはパスフレーズやパスワードに対する攻撃としては「辞書攻撃」や「レインボー攻撃」など様々なものがあり,知られている単語(あるいはその機械的変形)を組み合わせた程度では比較的簡単に破られてしまうことが知られています。 その辺を踏まえてパスフレーズやパスワードの設定は慎重に行うことをお薦めします。

X.509 と OpenPGP

私達がよく知っている PKI(Public Key Infrastructure; 公開鍵基盤)としては X.509 があります。 これは,通信経路の暗号化で使用する SSL/TLS やメールの暗号化で利用する S/MIME などに広く採用されています。 X.509 は権威的な CA(Certification Authority; 認証局)をノードとしたツリー型(ピラミッド型)の構成になっていて,ユーザは公開鍵を受け取った CA を信用することで公開鍵を認証します。

一方, OpenPGP も PKI の一種ですが X.509 とはかなり仕組みが異なります。 権威的な CA は存在せず(鍵サーバは公開鍵を認証しません)公開鍵の認証はユーザ自身が行い,ユーザを中心とした水平型の「信用の輪(web of trust)」を構成しています。 何故このような構成になっているかというと, OpenPGP は信頼できる(政府組織や企業のような)第3者認証機関が存在しなくても最低限機能するよう設計されているからです。

(PKI の機能としては少なくとも

  • 利用者を登録し,公開鍵証明書を発行する
  • 公開鍵が執行した場合には公開鍵証明書を破棄する
  • 検証のために公開鍵証明書を保管する

OpenPGPとPKI より)が必要です。 OpenPGP はこれらの機能をユーザ自身が行うため CA を必要としません。

ちなみに「公開鍵証明書」とはざっくりと「公開鍵+電子署名」と考えていただいて構いません)

X.509 と OpenPGP の違いを以下に示します。

特徴 X.509 OpenPGP
PKI の形態 hierarchical PKItrust-file PKI
公開鍵の認証者 専門機関(CA) 各ユーザ
信頼点 ルート CA 利用者自身(面識)
認証の連鎖構造 ツリー型 ユーザ中心型
認証者を認証する根拠利用者による選択利用者自身
証明書の破棄 あり 不完全
コスト 高い 低い
X.509 と OpenPGP の相違点(OpenPGPとPKI 2.3節より)

「証明書の破棄」については補足が必要かもしれません。 X.509 では何らかの理由で公開鍵が失効した場合,CA が証明書失効リスト(Certificate Revocation List; CRL; RFC5280)を発行し,下位の CA またはユーザに通知しますが, OpenPGP の場合は公開鍵ごとに失効証明書を作成し鍵の利用者に配布しなければなりません(OpenPGP 鍵の生成から失効まで参照)。 このため,ユーザに失効証明書が届かない場合は気づかずに公開鍵を利用し続ける可能性があります。

この煩雑さを軽減するために,鍵サーバを利用することが考えられます。 鍵サーバに失効証明書をアップロードすると該当の公開鍵の状態が revoke(失効)になります。 公開鍵の利用者は鍵サーバから鍵を更新することで失効させることができます。

OpenPGP は Peer-to-Peer でアドホックなシステムに向いています。 たとえばメッセンジャー・アプリの Conversations は XMPP(Extensible Messaging and Presence Protocol) 上で OpenPGP を用いた End-to-Eend 暗号化通信に対応しています。

X.509 はアドホックな運用には向いていないものの継続的かつ安定した認証サービスであり,既に SSL/TLS などで確固たる実績を誇っています。

X.509 と OpenPGP は機能的に直交するサービスであるため今後も相補的な運用が期待されています。 ちなみに GnuPG 2.x 系では X.509 と OpenPGP の両方の PKI をサポートしています。

参考文献

参考になる(かもしれない) Web ページ

参考図書

photo
暗号化 プライバシーを救った反乱者たち
スティーブン・レビー
斉藤 隆央 (翻訳)
紀伊國屋書店 2002-02-16
Book 単行本
ASIN: 4314009071, EAN: 9784314009072
評価     

20世紀末,暗号技術の世界で何があったのか。知りたかったらこちらを読むべし!

reviewed by Spiegel on 2018-12-16 (powered by amazon-item v0.2.0)

photo
PGP―暗号メールと電子署名
シムソン ガーフィンケル
Simson Garfinkel (原著), ユニテック (翻訳)
オライリー・ジャパン 1996-04
Book 単行本
ASIN: 4900900028, EAN: 9784900900028
評価     

良書なのだが,残念ながら内容が古すぎた。 PGP の歴史資料として読むならいいかもしれない。

reviewed by Spiegel on 2014-10-16 (powered by amazon-item v0.2.0)

photo
暗号技術入門 第3版 秘密の国のアリス
結城 浩
SBクリエイティブ 2015-08-25 (Release 2015-09-17)
eBooks Kindle版
ASIN: B015643CPE
評価     

SHA-3 や Bitcoin/Blockchain など新しい知見や技術要素を大幅追加。暗号技術を使うだけならこれ1冊でとりあえず無問題。

reviewed by Spiegel on 2015-09-20 (powered by amazon-item v0.2.0)