Skip to content

MS_EncryptionAlgorithms

nishi_74322014 edited this page Aug 4, 2026 · 1 revision

暗号化アルゴリズム

概要

ここでは、暗号化アルゴリズムの概要を解説する。

ハッシュ化

ハッシュ化とは、「ハッシュ関数」を用いて指定のメッセージの「ハッシュ値」を求める行為である。

ハッシュ値

「メッセージ ダイジェスト」、あるいは単に「ダイジェスト」と呼ぶことがある。
ダイジェスト認証や、「チャレンジ&レスポンス認証」で使用されている。
目的によってはハッシュ値のことを「フィンガープリント」、「チェックサム」とも呼ぶ。

ハッシュ関数

ここでは、正確には「暗号学的」ハッシュ関数について。

  • 情報セキュリティ分野で認証、署名など、様々に利用されている。
  • また、通常のハッシュ関数としても利用でき、
    ハッシュテーブル、ダイジェスト、データの一意識別・重複検出、チェックサムなどにも利用されている。
  • 既成の「ハッシュ関数」を使用した場合、以下が満たされているものとして利用できる。
性質 内容
原像計算困難性(不可逆性 / 一方向性) ハッシュ値から元のメッセージを得ることが事実上不可能
第二原像計算困難性 与えられたメッセージと同じハッシュ値を持つ別のメッセージを求めることが事実上不可能
衝突発見困難性 同じハッシュ値を持つ2つのメッセージの組を求めることが事実上不可能

暗号学的ハッシュ関数

以下の順序で(破るのが)難しい。

  1. 原像計算困難性
  2. 第二原像計算困難性
  3. 衝突発見困難性

移行メモ(正誤): 原文は 「衝突発見困難性=ハッシュ値を変えずに元のメッセージを改ざんできない」 「第二原像計算困難性=同じハッシュ値を持つ2つのメッセージを求められない(すりかえ)」 としていたが、両者の説明が入れ替わっている

  • 第二原像:「特定のメッセージに対して」同じハッシュ値の別メッセージを探す(=改ざん)
  • 衝突:「任意の」2つのメッセージの組を探す(探索の自由度が高いぶん破りやすい)

上表のとおりに整理した。原文の「難しい順序」の並び自体は正しい。

安全性

キーなし方式・あり方式

「暗号学的ハッシュ関数」には、ハッシュ計算用のキーを取れないもの(キーなし方式)と、
キーを取れるもの(キーあり方式)が存在する。

「暗号学的ハッシュ関数」自体は不可逆であるものの、
「キーなし方式」の場合、辞書攻撃により容易にメッセージが割れる可能性がある。

衝突耐性

「暗号学的ハッシュ関数」を使用する際は、最新の「ハッシュの衝突耐性」の情報を入手する事が推奨される。
これは、MD5、SHA-0、SHA-1 について衝突を発見する攻撃が知られているためである。

補足(最新化): SHA-1 は 2017年に実際の衝突(SHAttered)が示され、 2020年には選択プレフィックス衝突も実証された。 現在は証明書・署名用途で全面的に禁止されている。 新規は SHA-256 以上、または SHA-3 を使う。

.NETの暗号学的ハッシュ関数のプロバイダ

暗号化

暗号化の方式には、大きく分けて、

  • 秘密鍵・暗号化… 暗号化と復号が同じ処理であるところから、「対称アルゴリズム」とも呼ばれる。
  • 公開鍵・暗号化… 暗号化と復号が違う処理であるところから、「非対称アルゴリズム」とも呼ばれる。

の2つの方式がある。両者のメリット・デメリットを考慮し、両者を組み合わせたハイブリッドの方式もある。

暗号化方式の比較

  • ※1:「秘密鍵・暗号化」は、暗号化と復号化に使用する鍵が同一の秘密鍵であることから、
    「共通鍵・暗号化方式」とも呼ばれる。
  • ※2:「秘密鍵・暗号化」の鍵はパスワードのようなもので、基本的に相手毎に変えることが望ましい。
    従って、相手が増えるほど管理する秘密鍵が増える。
  • ※3:アルゴリズムが非対称であると、数学的に難しい処理が多く、高速での処理が難しくなるため。

秘密鍵・暗号化

  • 秘密鍵を使用して暗号化・復号化を行う。秘密鍵として、任意のキー(パスワード)を使用できる。
  • この方式は、秘密鍵の受け渡しと管理が困難となるため、
    不特定多数のユーザとネットワーク越しの情報受け渡しを行う C/S システムには使用されない。
  • 方式に「ストリーム暗号」、「ブロック暗号」がある。
  • アルゴリズム:DES、RC2、Rijndael(AES)、3DES
  • 鍵の数:n 人で、n(n−1)/2 個の鍵が必要になる。

公開鍵・暗号化

  • 秘密鍵・公開鍵のキー・ペアを生成する。
  • 公開鍵で暗号化したものは秘密鍵でしか復号できないという性質を利用して、
    不特定多数のユーザとネットワーク越しの情報受け渡しを行う C/S システムに使用される。

処理シーケンス

  1. 送信側は、「受信側の公開鍵」を取得する。
  2. 送信側は、平文を「受信側の公開鍵」で暗号化する。
  3. 暗号化された平文を送付する。
  4. 受信側は、平文を「受信側の秘密鍵」で復号化する。

公開鍵・暗号化方式

  • アルゴリズム:RSA
  • 鍵の数:n 人で、2n 個の鍵が必要になる。
  • .NET の RSACryptoServiceProvider を使用した場合、
    同じ公開鍵を使用しても暗号化情報は可変になるが、同じ秘密鍵で復号化が可能であるので、
    リプレイ攻撃の対象になる。チャレンジを加えるなどの実装を追加する必要がある。

ハイブリッド・暗号化(キー交換)

秘密鍵・暗号化、公開鍵・暗号化の両者のメリットとデメリットを考慮し、組み合わせた方式。

処理シーケンス

  1. 送信側は、「受信側の公開鍵」を取得する。
  2. 送信側は、「送信側の秘密(共通)鍵」を、「受信側の公開鍵」で暗号化する。
  3. 暗号化された「送信側の秘密(共通)鍵」を送付する。
  4. 受信側は、それを「受信側の秘密鍵」で復号化する。
  5. 送信側は、平文を「送信側の秘密(共通)鍵」で暗号化する。
  6. 暗号化された平文を送付する。
  7. 受信側は、平文を「送信側の秘密(共通)鍵」で復号化する。

ハイブリッド・暗号化方式

  • 「公開鍵・暗号化」で共通鍵を共有し、平文自体は速度の速い「秘密鍵・暗号化」で処理するため、
    「安全性」を落とさずに処理速度を稼ぐことができる。
  • 共通鍵(セッション鍵)をセッション毎に変更すれば、
    万一解読されても短い時間しかクラッキングできなくなる。
  • なお、SSL/TLSもこの「ハイブリッド・暗号化方式」を採用している。

PFS(Perfect Forward Secrecy)

  • 暗号文と、その暗号文を復号するための長期秘密鍵が漏洩しても、
    過去の暗号文を復号できない、という鍵交換に関する概念。
  • PFS を実現可能にするためのアルゴリズム
    • DHE:ディフィー・ヘルマン鍵共有
    • ECDHE:楕円曲線ディフィー・ヘルマン鍵共有
  • SSL/TLS では、証明書と組み合わせた DHE-RSA / DHE-DSA / ECDHE-RSA / ECDHE-ECDSA を使う。

移行メモ(誤記・正誤): 原文の「Perfect Forward Security」は Perfect Forward Secrecy が正しい(前方秘匿性)。

また「暗号文とその暗号文を復号するための秘密鍵が両方漏洩しても復号できない」という説明は 論理的に成立しない。正しくは 「サーバの長期秘密鍵が漏洩しても、過去に記録された通信を復号できない」。 セッションごとの一時鍵(ephemeral)を使い、通信後に破棄するため。

なお TLS 1.3 では鍵交換が (EC)DHE のみになり、PFS は常に有効。

デジタル署名

「デジタル署名」は、元となるメッセージのハッシュを秘密鍵で処理したものである。
送信元がこれをメッセージと同梱して送付することにより、
送信先は、元となるメッセージの正当性を(=改ざんされていない事を)検証できる。

処理シーケンス

  1. 送信側は、「メッセージ」から「メッセージのハッシュ」を求め、
    これを「送信側の秘密鍵」で処理することで、「デジタル署名」を生成する。
  2. 送信側は、「メッセージ」、「デジタル署名」を送付する。
  3. 受信側は、「デジタル署名」を「送信側の公開鍵」を使用して検証する。

デジタル署名

移行メモ: 原文は署名を「秘密鍵で暗号化し、公開鍵で復号化」と説明しているが、 これは RSA に限った実装上の類推であり、一般には誤り。 DSA / ECDSA には「秘密鍵で暗号化する」という操作自体が存在しない。 正しくは「署名生成」と「署名検証」という別々の操作。 RSA でも、実際の署名は PKCS#1 v1.5 や PSS のパディングを伴い、 暗号化とは異なる処理になる。

認証

メッセージ認証符号(MAC)

  • MAC: Message Authentication Code
  • 共通鍵を使って、メッセージの完全性と真正性を保証する短いデータ。
  • 暗号学的ハッシュ関数との違い:
    MAC 関数は選択平文攻撃における存在的偽造に対して耐性がなければならない。
  • アルゴリズム
    • ハッシュ関数(キーあり方式)を使う方式(HMAC)
    • ブロック暗号アルゴリズムを使う方式(OMAC/CMAC、CBC-MAC、PMAC)

※ ハッシュ(SHA-256 等)は「改ざんされていないこと」しか示せないが、
MAC は鍵を持つ者だけが作れるため「誰が作ったか(真正性)」も担保できる。

認証付き暗号(AEAD)

  • AE: Authenticated Encryption / AEAD: Authenticated Encryption with Associated Data
  • MAC と対称暗号を組み合わせて、機密性(暗号)、認証・正真性(MAC)を満たす仕組み。
  • 不適切に細工された暗号文を識別して復号を拒否できるため、選択暗号文攻撃に対して安全になる。
  • 組み合わせ方には3通りがあり、
    Encrypt-then-MAC (EtM) が適応的選択暗号文攻撃に対し安全であることが実証されている。
    • Encrypt-then-MAC (EtM)
    • Encrypt-and-MAC (E&M)
    • MAC-then-Encrypt (MtE)

補足(最新化): 現在の標準は AES-GCMChaCha20-Poly1305。 TLS 1.3 では暗号スイートが AEAD のみに限定された (旧来の CBC + HMAC(MtE)は Lucky Thirteen 等の原因になったため排除)。

その他

パスワードを格納する方式

Web サイトの Forms 認証などを実装する場合、ハッシュのみ保管が一般的。

方式 内容
ハッシュのみ保管 パスワードのハッシュ値のみ保存。鍵管理が不要。ただしパスワードの平文が取得できないため、リマインダやチャレンジ&レスポンスは併用できない
暗号化して保管 昨今、あまり選択されない方式

ベスト・プラクティス

  • 「キーなし方式」+ソルトストレッチング
    • ソルト:同じパスワードでもユーザーごとに異なるハッシュ値にできる(レインボー・テーブル対策)。
      ソルトはハッシュ値とともに保存する。
    • ストレッチング:高速なハッシュを繰り返し用いることで速度を遅くし、オフライン総当たり攻撃を妨害する。
  • 業界的ベスト・プラクティスの bcrypt(Blowfish 暗号が基盤)が、各言語ごとライブラリが存在する。
  • また、bcrypt の後継として Argon2 が注目されている。

補足(最新化): 現在の推奨は Argon2id(OWASP の第一推奨)。 次点で scrypt、bcrypt、PBKDF2。 いずれも「メモリ困難性」を持たせて GPU / ASIC による並列総当たりを不利にするのが要点。 汎用ハッシュ(SHA-256 等)を単純に繰り返すだけの自作ストレッチングは避ける。

ネットワークへパスワードを流す方式

方式 内容
HTTPS 一般的にはコレ。共通鍵が通信セッション毎に可変となるため、リプレイ攻撃にも対処できる
チャレンジ&レスポンス NTLM や CHAP などで採用。チャレンジ(乱数)とキーあり方式のハッシュでパスワードをハッシュ化して流す。認証基盤側はパスワードを平文(または可逆な形)で保持している必要がある
公開鍵・暗号化 同じ秘密鍵で復号可能なため、そのままではリプレイ攻撃の対象。チャレンジを加える等の実装が必要

ネットワークへ認証チケットを流す方式

OpenID Connect における JWT の用例などが参考になる。

暗号化の詳細

初期化ベクトル

初期化ベクトル(IV: Initialization Vector)

※ IV は秘密である必要はないが、同じ鍵で使い回してはならない
使い回すと同一平文が同一暗号文になり、解析の手がかりを与える。

ストリーム暗号

  • ビット、バイト、文字毎に処理
  • ブロック暗号より仕組みが単純で高速
  • 暗号化してもデータサイズが変化しない(通信処理に適する)。
  • 鍵ストリーム(擬似乱数列)を共通鍵や初期化ベクトルをシードとして生成し、
    平文 / 暗号文との排他的論理和で暗号化 / 復号化する。
  • アルゴリズム:KCipher-2、Salsa20、RC4(危殆化)、MUGI、A5/1(脆弱性)

※ 現在は ChaCha20(Salsa20 の改良)が主流。RC4 は TLS で禁止済み。

ブロック暗号

  • ブロック毎に処理。ストリーム暗号より仕組みが複雑で低速。
  • 空きはパディングするのでデータサイズが増加する。
  • そのままでは暗号強度が弱いので、前ブロック値を排他的論理和に使用する暗号化モードがある。
  • アルゴリズム:AES(DES の後継)、DES / DES-X / 3DES、RC2 / RC5 / RC6、IDEA、Camellia、CAST-128 / CAST-256

移行メモ(正誤): 原文は「通常、暗号化は鍵のサイズと同じバイト長を1ブロックとする。 1024ビットの鍵ならば 128バイトを1ブロック」と説明していたが、 ブロック長と鍵長は独立である。 例えば AES はブロック長が 常に 128 ビット(16バイト) で、 鍵長は 128 / 192 / 256 ビットから選べる。 また 1024 ビット鍵はブロック暗号ではなく RSA 等の公開鍵暗号の話。

暗号化モード(暗号利用モード)

  • 認証用の利用モード:CCM、OCB、XCBC、XCBC-MAC
  • 秘匿用の利用モード
# モード 特徴
1 ECB: Electronic CodeBook 単純にブロックに分割しそのまま暗号化するため、IV を必要としない。鍵とデータが同じなら同じ暗号文になるため、暗号文一致攻撃・改ざん攻撃に弱い
2 CBC: Cipher Block Chaining 前の暗号化ブロックと XOR してから暗号化。最初のブロックは IV を使う
3 CFB: Cipher-FeedBack 前のブロックを暗号化した結果と XOR する(ストリーム暗号的)
4 OFB: Output FeedBack IV を繰り返し暗号化して鍵ストリームを生成し、XOR する
5 GCM: Galois/Counter Mode CTR モード+認証タグ。現在の標準(AEAD

ECB は使わないのが鉄則(画像を ECB で暗号化すると元の絵が透けて見える例が有名)。

パディングモード(パディング方式)

  • NoPadding … パディングしない
  • ZeroBytePadding … NULL バイト(0x00) でパディング。元データに NULL が含まれない場合のみ
  • PKCS #5 / #7 Padding … ブロック長に満たないサイズの値を表すバイト値で足りない分を埋める

公開鍵・暗号化の詳細

RSA

  • RSA : Rivest-Shamir-Adleman cryptosystem
  • 大きな合成数の素因数分解の困難性に依る。
  • 暗号化にも署名にも使える。

DSA

  • DSA : Digital Signature Algorithm
  • 離散対数問題 の困難性に依る。
  • 署名専用(暗号化には使えない)。

ECC(ECDSA, ECDH)

  • ECC : Elliptic Curve Cryptography
  • 楕円曲線を利用した暗号方式の総称。楕円曲線上の離散対数問題の困難性に依る。
  • ECDSA(Elliptic Curve DSA)… DSA を楕円曲線上で定義。デジタル署名に利用できる。
  • ECDH(Elliptic curve Diffie–Hellman key exchange)… DH 鍵共有を楕円化。
    共通鍵の共有のための暗号化に利用できる。

※ ECC は RSA より短い鍵で同等の強度を得られる
(ECC 256bit ≒ RSA 3072bit)。処理も軽いため、TLS の主流になっている。

離散対数問題

  • 2つのノードは素数 p と定数 g(p より小さい)を共有する。
  • y(≒公開鍵)から x(≒秘密鍵)を求めるのが困難であることを利用する。

DH鍵共有(交換)

Diffie–Hellman key exchange。
互いに秘密鍵を持ち、公開鍵を交換することで、
通信路に共通鍵そのものを流さずに同じ共通鍵を導出できる。

参考


Tags: セキュリティ, 暗号化, 証明書

NetDevInfraWiki

マイクロソフト系技術情報 Wiki
Open 棟梁 Wiki

(未着手)

開発基盤部会 Wiki

移行管理: DONETODO

Clone this wiki locally