blog

暗号技術 - メッセージ認証コード

1.暗号入門 2.対称暗号 3.グループ暗号モード 4.非対称暗号 5.一方向ハッシュ関数 6.メッセージ認証コード 7.電子署名 8.証明書 メッセージ認証コードとは アリスとボブの話 $$ アカウ...

Mar 28, 2020 · 8 min. read
シェア
"メッセージ認証コード--- メッセージは正しく届いたか??"

メッセージ認証コードとは

  • アリスとボブの物語

    前回同様、アリスとボブの物語から始まります。しかし、今回はアリスとボブは2つの別々の銀行で、アリスの銀行はインターネットでボブの銀行に送金依頼を送り、ボブの銀行は次のような依頼を受け取ります:

    アカウントからA 7354アカウントにB 7661送金0010ミリオン口座A-7354から口座B-7661への$00.1百万ドルの送金

    もちろん、ボブの銀行が受信した送金依頼の内容は、アリスの銀行が送信した内容と同一でなければなりません。もし能動的な攻撃者であるマロリーが、アリス銀行から送られた送金依頼を途中で改ざんした場合、ボブの銀行はその改ざんを認識できなければなりません。そうでなければ、マロリーが受取口座を自分の口座に変更していれば、1000万ドルが盗まれていたことになります。

    つまり、この送金依頼はアリス銀行から送られたものなのでしょうか?アリス銀行が送金依頼を送ったのではなく、アリス銀行になりすました攻撃者マロリーが送った可能性があります。もし送金依頼がアリス銀行から送られていないのであれば、送金は実行されなかったはずです。

    現在懸念されているのは、送金依頼の「完全性」と「認証」です。

    メッセージの完全性は一貫性とも呼ばれ、メッセージが改ざんされていないという性質を指します。送金依頼の内容がアリス銀行から送られた内容と全く同じであることが確認できれば、メッセージの完全性を確認することと同じで、メッセージが改ざんされていないことを意味します。

    メッセージの認証とは、そのメッセージが正しい送信者からのものであるという性質を指します。もし送金要求が実際にアリス銀行から来たことが確認できれば、これはメッセージを認証することに等しく、メッセージは送信者になりすました誰かによって送信されたものではないということになります。

    この章で説明するメッセージ認証コードを使用することで、改ざんとマスカレードの両方を認識することができます。

  • メッセージ認証コードとは

    メッセージ認証コード(Message Authentication Code)は、3つの単語の頭文字をとってMACと略され、完全性を確認し、認証を行うための技術。

    メッセージ認証コードの入力は、任意の長さのメッセージと、送信者と受信者の間で共有される鍵で構成され、MAC値と呼ばれる固定長のデータを出力することができます。

    任意の長さのメッセージに基づいて固定長のデータを出力することは、一方向ハッシュ関数と非常によく似ています。しかし、一方向ハッシュ関数はハッシュ値を計算するために鍵を必要としませんが、メッセージ認証コードは送信者と受信者の間で共有される鍵を使用する必要があります。

    MACを計算するためには共有鍵を保持する必要があり、共有鍵がなければMAC値を計算することはできません。メッセージ認証コードが認証を達成するために使用するのは、この性質です。また、一方向ハッシュ関数のハッシュ値と同様に、メッセージに1ビットの変化があってもMAC値に変化が生じるため、メッセージ認証コードはこの性質を利用して完全性を確認します。

    メッセージ認証コードを実装する方法はたくさんありますが、一時的に次のように理解することができます:メッセージ認証コードは、キーに関連付けられた一方向ハッシュ関数です。

     				 **一方向ハッシュ関数とメッセージ認証コードの比較**
    

メッセージ認証コードの使用手順

アリスの銀行とボブの銀行の話を例に、メッセージ認証コードを使う手順を説明します。

  1. 送信者であるアリスと受信者であるボブは事前に鍵を共有します。
  2. 送信者Aliceは送金要求メッセージに基づいてMAC値を計算します。
  3. 送信者であるアリスは、送金要求メッセージとMAC値の両方を受信者であるボブに送信します。
  4. 受信側Bobは、受信した送金要求メッセージに基づいてMAC値を計算します。
  5. 受信者のボブは、計算したMAC値とアリスから受信したMAC値を比較します。
  6. もし2つのMAC値が一致すれば、受信者のボブは送金要求がアリスから来たと結論づけることができます。

HMAC

HMAC

HMACは、一方向ハッシュ関数を使用してメッセージ認証コードを構築する方法であり、HMACのHはハッシュを意味します。

HMACで使用される一方向ハッシュ関数は1種類に限定されず、強度の高い一方向ハッシュ関数であれば何でも使用できますし、将来新しい一方向ハッシュ関数が設計されれば、それを使用することも可能です。

SHA-I、MD5、およびRIPEMD-160を使用して構築されたHMACは、それぞれHMAC-SHA-1、HMAC-MD5、およびHMAC-RlPEMDと呼ばれます。

			**HMACの内部実装では、秘密鍵を使用してメッセージのメッセージ認証コードを生成する。** 

上記のプロセスは、最終的に得られるMAC値は、受信メッセージとキーの両方に関連する固定長のビット列でなければならないことを示しています。

GoHMACの使用

必要なパッケージ

import "crypto/hmac"

使用機能

func New(h func() hash.Hash, key []byte) hash.Hash
func Equal(mac1, mac2 []byte) bool
  1. hamc.New 関数
    • 引数 1: ハッシュチェックサムアルゴリズムを使用する新しい hash.Hash インターフェイスを作成します。
      • md5.New()
      • sha1.New()
      • sha256.New()
    • パラメータ 2: 使用する秘密鍵
    • 戻り値: データの追加とメッセージ認証コードの計算を行うハッシュ・インターフェース
      • データの追加: Write(p []byte)
      • 計算結果: Sum(b []byte) []byte
  2. hmac.Equal関数
    • 2つのMACが同じかどうかを比較します。

メッセージ認証コードの生成

// メッセージ認証コードの生成
func GenerateHMAC(src, key []byte) []byte {
	// 1. sha256アルゴリズムでハッシュを作成する。.Hash  
	myHmac := hmac.New(sha256.New, key)
	// 2. テストデータの追加
	myHmac.Write(src)
	// 3. 計算結果
	result := myHmac.Sum(nil)
	return result
}

重要な機能の説明

  1. 一番下のハッシュ・アルゴリズムを使用するhash.Hashインターフェイスを作成します。

    パッケージに対応する関数: "crypto/hmac"
    func New(h func() hash.Hash, key []byte) hash.Hash
     - パラメータ h: 関数ポインタ、戻り値はハッシュ.Hash, など、新方式に対応するハッシュアルゴリズムを使用することができる。:
     -- md5.New
     -- sha1.New
     -- sha256.New
     -- sha256.New224
     -- sha512.New
     -- sha512.New384
     - 引数 key: データと混合するための秘密鍵
     -  : hash.Hash  
    

メッセージ認証コードの検証

func VerifyHMAC(res, src, key []byte) bool {
	// 1. sha256アルゴリズムでハッシュを作成する。.Hash  
	myHmac := hmac.New(sha256.New, key)
	// 2. テストデータの追加
	myHmac.Write(src)
	// 3. 計算結果
	result := myHmac.Sum(nil)
	// 4. 比較結果
	return hmac.Equal(res, result)
}

重要な機能の説明

  1. 2つのMACが同じかどうかの比較

    パッケージに対応する関数: "crypto/hmac"
    func Equal(mac1, mac2 []byte) bool
     - 引数 mac1, mac2: ハッシュ・アルゴリズムによって計算されるメッセージ認証コード
     -  : ここでは紹介しない。==mac2, 真を返す。; そうでない場合は、偽を返す。
    

テストコード

func HMacTest() {
	key := []byte("メッセージ認証キー")
	src := []byte("メッセージ認証コードのテストデータ")
	result := GenerateHMAC(src, key)
	final := VerifyHMAC(result, src, key)
	if final {
		fmt.Println("メッセージ認証コード 認証成功!!!")
	} else {
		fmt.Println("メッセージ認証コード 認証失敗......")
	}
}

メッセージ認証コードの鍵配布問題

メッセージ認証コードでは、送信者と受信者の間でキーを共有する必要があり、このキーにアクティブな攻撃者であるマロリーがアクセスすることはできません。この鍵がマロリーの手に渡ると、マロリーはMAC値も計算できるため、改ざんやマスカレード攻撃を自由に行うことができ、メッセージ認証コードは機能しなくなります。

送信者と受信者は、導入された対称暗号と同じように鍵を共有する必要があります。実際、対称暗号の鍵配布の問題はメッセージ認証コードでも発生します。秘密鍵の配布については、後のセクションで非対称暗号を使って解決する方法を説明します。

メッセージ認証コードでは解決できない問題

送信者Aliceが受信者Bobにメッセージを送りたいと仮定すると、メッセージ認証コードが使われた場合、受信者Bobは受信したメッセージが送信者Aliceが送ったものと同じだと結論づけることができます。を改ざんしたり、アリスを装ってメッセージを送っても、 ボブはメッセージの改ざんや偽装を認識することができます。

しかし、「第三者への証明」と「否認の防止」という2つの問題は、メッセージ認証コードでは解決できません。以下、それぞれについて説明します。

第三者に対する認証

ボブはアリスからメッセージを受け取った後、第三者の認証者であるビクターに、そのメッセージが本当にアリスから送られたものであることを証明したいとします。

まず、ビクターがMAC値を検証するためには、アリスとボブの間で共有されている鍵を知る必要があります。

ボブがビクターを信頼し、ビクターに鍵を教えることに同意したと仮定すると、それでもビクターはそのメッセージがアリスから送られたものだとはわかりません。なぜなら、ビクターは "MAC値が正しくても、このメッセージを送った人はアリスとは限らず、ボブかもしれない "と考えることができるからです。

正しいMAC値を計算できるのはアリスとボブだけであり、二人の間で通信を行う場合、この鍵を共有している二人のうちの一人が自分自身であることから、相手がMAC値を計算したと結論づけることができます。しかし、第三者であるVictorの場合、AliceやBobはMAC値を計算したのが自分ではなく相手であることを証明できません。

第三者への証明は、第7章で説明するデジタル署名を用いて実現できます。

####6.4.2 拒否に対する保護

ボブがアリスとボブが共有する鍵を使って計算された MAC値を含むメッセージを受け取ったとします。

しかし、前述のように、ボブはこのことを検証者であるビクターに証明することはできません。つまり、送信者であるアリスはビクターに対して、"私はこのメッセージをボブに送っていない "と主張することができます。このような行為は否定と呼ばれます。

BobがMAC値を取って証明したとしても、VictorはAliceとBobの主張のどちらが正しいか、つまりメッセージ認証コードで否定を防ぐ方法はありません。

概要

メッセージ認証コードとは、メッセージを認証し、その完全性を確認する技術。送信者と受信者の間で共有される鍵を使用することで、なりすましや改ざんの有無を識別することができます。

メッセージ認証コードは、一方向ハッシュ関数HMACを使用することができ、対称暗号化も達成することができますが、ここでは紹介しません。

メッセージ認証符号では、送信者と受信者が同じ鍵を共有するため、第三者に証明できない、否認を防止できないなどの問題が生じます。次章では、これらの問題を解決する電子署名を紹介します。

Read next

決定版 Https ガイド (I) からのメモ

ハッシュ関数は、任意の長さの入力を一定の長さの出力に変換するアルゴリズムです。暗号ハッシュ関数のいくつかの付加的な特性:抗原性(単一)

Mar 28, 2020 · 2 min read