(Translated by https://www.hiragana.jp/)
MD5 - Wikipedia コンテンツにスキップ

MD5

出典しゅってん: フリー百科ひゃっか事典じてん『ウィキペディア(Wikipedia)』
MD5
一般いっぱん
設計せっけいしゃ ロナルド・リベスト
初版しょはん発行はっこう 1992ねん4がつ
シリーズ MD2, MD4, MD5, MD6
詳細しょうさい
ダイジェストちょう 128 bit
構造こうぞう Merkle-Damgård construction
ラウンドすう 4 [1]
最良さいりょう暗号あんごう解読かいどくほう
2009ねんにTao Xie、Dengguo Fengによってつよ衝突しょうとつたいせいやぶられている (220.96 time)。通常つうじょうのコンピュータですうびょう可能かのう[2]

MD5(エムディーファイブ、えい: message digest algorithm 5)は、暗号あんごうがくてきハッシュ関数かんすうのひとつである。ハッシュは128ビット。

概要がいよう

[編集へんしゅう]

MD4前身ぜんしんであり、安全あんぜんせい向上こうじょうさせたもの。1991ねん開発かいはつされた。開発かいはつしゃはMD4とおなじくロナルド・リベスト

d41d8cd98f00b204e9800998ecf8427e

のようなハッシュられる。

用途ようと

[編集へんしゅう]

一般いっぱんてき暗号あんごうがくてきハッシュ関数かんすう同様どうよう使用しようできる。ただし、後述こうじゅつ脆弱ぜいじゃくせいがあり強度きょうど必要ひつよう場合ばあいには使つかってはいけない。

実際じっさい使用しようれい

[編集へんしゅう]

FreeBSDはインストール可能かのうなCDイメージと、それのMD5同時どうじ配布はいふしている。(MD5改変かいへんはないと仮定かていして)インストール可能かのうなCDイメージが、途中とちゅう改変かいへんされていないことを確認かくにんしてみる。

  1. md5 コマンドを、イメージファイルに実行じっこうする。
    localhost% md5 5.1-RELEASE-i386-miniinst.iso
    MD5 (5.1-RELEASE-i386-miniinst.iso) = 646da9ae5d90e6b51b06ede01b9fed67
  2. CHECKSUM.MD5の中身なかみ確認かくにんし、一致いっちしていれば破損はそん可能かのうせいきわめてひくいことがかる。
    localhost% cat CHECKSUM.MD5
    MD5 (5.1-RELEASE-i386-disc1.iso) = 3b6619cffb5f96e1acfa578badae372f
    MD5 (5.1-RELEASE-i386-disc2.iso) = 2cfa746974210d68e96ee620bf842fb6
    MD5 (5.1-RELEASE-i386-miniinst.iso) = 646da9ae5d90e6b51b06ede01b9fed67

安全あんぜんせい

[編集へんしゅう]

MD5、およびRIPEMDとよばれるハッシュ関数かんすうには理論りろんてき弱点じゃくてん存在そんざいすることがあきらかとなっている[3][4]

2004ねん8がつ暗号あんごう国際こくさい会議かいぎ CRYPTO (のランプセッション)にて、MD5のコリジョンをもとめることができたという報告ほうこくがあった。理論りろんてき可能かのうせいとして、MD5をもちいて改竄かいざんされないことを確認かくにんする場合ばあい、あらかじめ正規せいきのファイルと不正ふせいなファイルを用意よういしておき、正規せいきのファイルを登録とうろくしておきながら、実際じっさいにはおなじMD5を不正ふせいなファイルにえる攻撃こうげきがありえることを意味いみする。また2007ねん11月、2つのまったことなる実行じっこうファイルをもとに、各々おのおの末尾まつびにデータブロックを付加ふかし、その部分ぶぶん変更へんこうしながら探索たんさくおこなうことにより、同一どういつのMD5をたせることに成功せいこうしたという報告ほうこくがあった。この攻撃こうげき方法ほうほう実証じっしょうされたことになる。

アメリカ合衆国あめりかがっしゅうこく政府せいふでは、MD5ではなく、Secure Hash Algorithm (SHA)を標準ひょうじゅんのハッシュとして使用しようしている。 日本にっぽんCRYPTRECでは、MD5を政府せいふ推奨すいしょう暗号あんごうリストからはずし、SHA-256 (SHA-2のバリエーション) 以上いじょう推奨すいしょうしている。

ハッシュの衝突しょうとつたいせいについて

[編集へんしゅう]

MD5 のハッシュについては、パソコンレベルでもすう10ふん程度ていどで、どういちハッシュユニークなデータれつ生成せいせいできる実装じっそうひろまっている。すなわち、つよ衝突しょうとつたいせい容易ようい突破とっぱされうる状態じょうたいにある(SHA-0/SHA-1アルゴリズムについても、MD5ほど容易よういではないが突破とっぱされる脆弱ぜいじゃくせい発見はっけんされている)。

一方いっぽう任意にんいあたえられたハッシュたいして、(なんらかのべつの)データを生成せいせいする実装じっそうひろまっているわけではない。すなわち、じゃく衝突しょうとつたいせい容易ようい突破とっぱされうるわけではない。また、任意にんいあたえられたハッシュたいして、改竄かいざんしゃ意図いとどおりのデータれつ容易ようい生成せいせいできるわけでもない(もしそうならば、それはすで暗号あんごうではない)。

つよ衝突しょうとつたいせい突破とっぱとはたとえば、同一どういつのハッシュユニークな2つのデータれつD1とD2のペアを1つ発見はっけんできた、ということである。なお、この場合ばあいD1やD2が意味いみつデータであるかどうかはわれない。また、データれつD3のハッシュがHであったとして、この"特定とくていの"ハッシュHにたいして、同一どういつのハッシュつようなほかのデータれつD4を発見はっけんできたとしたら、それはじゃく衝突しょうとつたいせい突破とっぱされたこと意味いみする(すなわち、D3とHのわせで改竄かいざんせい証明しょうめいできなくなる)。

そのため、ただちにこれらのハッシュアルゴリズムをもちいている暗号あんごう通信つうしん盗聴とうちょう改竄かいざんされたり、電子でんし署名しょめい有効ゆうこうせいくなるとうわけではない。しかし、つよ衝突しょうとつたいせい突破とっぱされたということは、将来しょうらいてきには攻撃こうげき手法しゅほう計算けいさん能力のうりょく進化しんかにより、じゃく衝突しょうとつたいせい突破とっぱされうるということ暗示あんじする。もしじゃく衝突しょうとつたいせい突破とっぱされたとしたら、もはや暗号あんごう通信つうしん電子でんし署名しょめい改竄かいざんせい証明しょうめいできなくなり、その暗号あんごう署名しょめいシステムは(なかば)意味いみする。

また、暗号あんごう署名しょめいシステムのintegrity(たとえば最良さいりょう攻撃こうげき手法しゅほうたいして十分じゅうぶん頑強がんきょうであるということ)にハッシュきょう衝突しょうとつたいせい突破とっぱ困難こんなんであるという前提ぜんていがもしった場合ばあいには、そのシステムのintegrityも当然とうぜんうしなわれることになる。Integrityを要求ようきゅうされるシステムでは、そのさい検証けんしょう最低限さいていげん必要ひつようとなる。

APOPの脆弱ぜいじゃくせい

[編集へんしゅう]

2007ねん4がつIPAはAPOP脆弱ぜいじゃくせいについて警告けいこくした[5]。これは電気通信大学でんきつうしんだいがく太田おおた和夫かずお暗号あんごう理論りろん)らが発見はっけんしたもので[6]、APOPのプロトコルじょう弱点じゃくてん利用りようして、MD5ハッシュから理論りろんてきもとのパスワードをもとめることが出来できるというものである。これの対策たいさくとしては、SSLの利用りよう推奨すいしょうされている。(そうたり攻撃こうげきほうによるツールはすで公表こうひょうされている)

Flame攻撃こうげきかんして

[編集へんしゅう]

2012ねん4がつ発覚はっかくした「Flame攻撃こうげき」(Microsoft Updateたいするなりすまし攻撃こうげき)において、一部いちぶデジタル証明しょうめいしょ署名しょめいアルゴリズムにMD5が使つかわれていたことから、MD5 の衝突しょうとつたいせいかんする脆弱ぜいじゃくせいをついて、デジタル証明しょうめいしょ偽造ぎぞうおこなわれたように一部いちぶ媒体ばいたいでは報道ほうどうされている[7]

しかし、べいソフォス (Sophos) しゃ記事きじによると[8]マイクロソフトがコード署名しょめい使用しようできるデジタル証明しょうめいしょであって、ターミナルサーバーライセンスインフラストラクチャ(中間なかまCertificate Authenticity)じょう使用しようできるものを、あやまって発行はっこうしていたこと原因げんいんとされている。また、Flameマルウェアが攻撃こうげき使用しようしたデジタル証明しょうめいしょ入手にゅうしゅした経路けいろ、また前述ぜんじゅつの MD5 で署名しょめいされた証明しょうめいしょをクラックして偽造ぎぞうしたものであるかかはあきらかになっていないとしている。一方いっぽうマイクロソフトは、Windows Vista以降いこうのバージョンにおけるコード署名しょめい検証けんしょう回避かいひするためには攻撃こうげきしゃが MD5 の衝突しょうとつ利用りようして特定とくてい拡張かくちょうフィールドを削除さくじょする必要ひつようがあったとしている[9]

マイクロソフトは2012ねん6月5にちに、問題もんだいとなったターミナルサーバーライセンスインフラストラクチャのなかあいだCertificate Authenticityを無効むこうするセキュリティアップデートを公開こうかいしている[10]

アルゴリズム

[編集へんしゅう]
1:MD5計算けいさんの1段階だんかい。MD5はこのような操作そうさを64かいおこなうが、16かい操作そうさを1ラウンドとして4ラウンドおこなう。F非線形ひせんけい関数かんすうで、1ラウンドごとに1つの関数かんすう使つかわれる。Miはメッセージの入力にゅうりょくKi操作そうさごとにことなる32ビットの定数ていすうである。left shiftsひだりへのsビットのローテーション操作そうさであり、s操作そうさごとにことなる。Additionは232ほうとした加算かさんである。

MD5は可変長かへんちょう入力にゅうりょく処理しょりして、128ビット固定こていちょう出力しゅつりょくする。入力にゅうりょくメッセージは512ビット(32ビットのワードが16)ごとにけられるが、ながさが512の倍数ばいすうとなるようにパディングおこなわれる。 パディングとしてはまずメッセージの最後さいごに1ビットの1をして、そのにはながさが512でって448あまる(つまり、512の倍数ばいすうに64りない)ながさになるようにひたすら0をしていく。そして、のこった64ビットにはもとのメッセージのながさ(の下位かい64ビット)をれることとなる。

MD5のメイン部分ぶぶんのアルゴリズムは32ビット×4ワード(それぞれのワードをABCDあらわす) = 128ビットの状態じょうたいって進行しんこうしていく。初期しょき状態じょうたいでは、この4ワードはまった定数ていすう初期しょきされており、 512ビットのブロックを順次じゅんじ使つかってこの状態じょうたい変化へんかさせていくのがMD5の中核ちゅうかくとなっている。1かい処理しょりでは非線形ひせんけい関数かんすうF、232ほうとした加算かさんひだりへのビットローテートおこなわれる。 そして、16かい操作そうさを1ラウンドとして、512ビットの入力にゅうりょくブロックを処理しょりするのに4ラウンドの処理しょりおこなわれる。Fには4とおりの関数かんすうがあり、ラウンドごとにことなるものが使つかわれる。

はそれぞれXORANDORNOT演算えんざん意味いみする。

擬似ぎじコード

[編集へんしゅう]

MD5ハッシュは、以下いか擬似ぎじコードでいたアルゴリズムで算出さんしゅつされる。はすべてリトルエンディアンとする。

function md5 (message : array[0..*] of bit) returns array[0..15] of unsignedInt8 is
    //ひだりローテート関数かんすう
    function leftRotate (x : unsignedInt32, c : integer range 0..31) returns unsignedInt32 is
    begin leftRotate := (x leftShift c) bitOr (x rightShift (32-c)) end ;

    function makeK (i : integer range 0..63) returns unsignedIt32 is
    begin makeK := floor(232×abs(sin(i + 1))) end ;

begin
//ちゅう: すべての変数へんすう符号ふごうなし32ビットで、けたがあふれたときは232ほうとして演算えんざんされるものとする。

//ラウンドごとのローテートりょう sを指定していする
const s : array[0..63] of unsignedInt32 :=
  {
   7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,  7, 12, 17, 22,
   5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,  5,  9, 14, 20,
   4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,  4, 11, 16, 23,
   6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21,  6, 10, 15, 21
  } ;

//整数せいすうラジアンのときの三角さんかく関数かんすうからKの生成せいせいする
const K : array[0..63] of unsignedInt32 := range 0..63 map makeK  ;

//(Kを事前じぜん計算けいさんして、テーブルとしておくこともできる)
//
//const K : array[0..63] of unsignedInt32 :=
//  {
//  D76AA478(16進数しんすう), E8C7B756(16進数しんすう), 242070DB(16進数しんすう), C1BDCEEE(16進数しんすう),
//  F57C0FAF(16進数しんすう), 4787C62A(16進数しんすう), A8304613(16進数しんすう), FD469501(16進数しんすう),
//  698098D8(16進数しんすう), 8B44F7AF(16進数しんすう), FFFF5BB1(16進数しんすう), 895CD7BE(16進数しんすう),
//  6B901122(16進数しんすう), FD987193(16進数しんすう), A679438E(16進数しんすう), 49B40821(16進数しんすう),
//  F61E2562(16進数しんすう), C040B340(16進数しんすう), 265E5A51(16進数しんすう), E9B6C7AA(16進数しんすう),
//  D62F105D(16進数しんすう), 02441453(16進数しんすう), D8A1E681(16進数しんすう), E7D3FBC8(16進数しんすう),
//  21E1CDE6(16進数しんすう), C33707D6(16進数しんすう), F4D50D87(16進数しんすう), 455A14ED(16進数しんすう),
//  A9E3E905(16進数しんすう), FCEFA3F8(16進数しんすう), 676F02D9(16進数しんすう), 8D2A4C8A(16進数しんすう),
//  FFFA3942(16進数しんすう), 8771F681(16進数しんすう), 6D9D6122(16進数しんすう), FDE5380C(16進数しんすう),
//  A4BEEA44(16進数しんすう), 4BDECFA9(16進数しんすう), F6BB4B60(16進数しんすう), BEBFBC70(16進数しんすう),
//  289B7EC6(16進数しんすう), EAA127FA(16進数しんすう), D4EF3085(16進数しんすう), 04881D05(16進数しんすう),
//  D9D4D039(16進数しんすう), E6DB99E5(16進数しんすう), 1FA27CF8(16進数しんすう), C4AC5665(16進数しんすう),
//  F4292244(16進数しんすう), 432AFF97(16進数しんすう), AB9423A7(16進数しんすう), FC93A039(16進数しんすう),
//  655B59C3(16進数しんすう), 8F0CCC92(16進数しんすう), FFEFF47D(16進数しんすう), 85845DD1(16進数しんすう),
//  6FA87E4F(16進数しんすう), FE2CE6E0(16進数しんすう), A3014314(16進数しんすう), 4E0811A1(16進数しんすう),
//  F7537E82(16進数しんすう), BD3AF235(16進数しんすう), 2AD7D2BB(16進数しんすう), EB86D391(16進数しんすう)
//  } ;

//A、B、C、Dの初期しょき
var a0 : unsignedInt32 := 67452301(16進数しんすう) ; // A
var b0 : unsignedInt32 := EFCDAB89(16進数しんすう) ; // B
var c0 : unsignedInt32 := 98BADCFE(16進数しんすう) ; // C
var d0 : unsignedInt32 := 10325476(16進数しんすう) ; // D

//パディング処理しょり: 1ビットのデータ「1」を追加ついかする
message[message.length] = (bit) 1 ;
//ちゅう: 入力にゅうりょくのバイトは、最高さいこうビットがさきのビットであるビット列びっとれつとして解釈かいしゃくするものとする[11]

const initial_message_length : integer := message.length ;

//パディング処理しょり: のこりは「0」でめる
repeat
    message[message.length] := (bit) 0
until (message.length mod 512) = 448 ; //448 = 512 - 64
message[message.length .. message.length+63] := split (initial_message_length mod 264, 1bit) ;

//入力にゅうりょくを512ビットのブロックにって、順次じゅんじ処理しょりする
//chunk のバイトオーダーは message のバイトオーダーのままである
var chunk : bits512 ;
for each chunk of split (message, 512bit) do
    var M : array [0..15] of unsignedInt32 := split (chunk, 32bit) ;
//内部ないぶ状態じょうたい初期しょき
    var A : unsignedInt32 := a0 ;
    var B : unsignedInt32 := b0 ;
    var C : unsignedInt32 := c0 ;
    var D : unsignedInt32 := d0 ;
//メインループ
    var F : unsignedInt32 ;
    var g : integer range 0..15 ;
    for i from 0 to 63
        switch
            case 0 ≦ i ≦ 15 do
                F := (B bitAnd C) bitOr ((bitNot B) bitAnd D) ;
                g := i
            end case
            case 16 ≦ i ≦ 31 do
                F := (D bitAnd B) bitOr ((bitNot D) bitAnd C) ;
                g := (5×i + 1) mod 16
            end case
            case 32 ≦ i ≦ 47 do
                F := (B bitXor C) bitXor D ;
                g := (3×i + 5) mod 16
            end case
            case 48 ≦ i ≦ 63 do
                F := C bitXor (B bitOr (bitNot D)) ;
                g := (7×i) mod 16
            end case
        end switch
        F := F + A + K[i] + M[g] ;
        (D, C, A) := (C, B, D) ;
        B := B + leftRotate(F, s[i]) ;
    end for ;
//いままでの結果けっかにこのブロックの結果けっか
    a0 := a0 + A ;
    b0 := b0 + B ;
    c0 := c0 + C ;
    d0 := d0 + D
end for ;

//16の8ビット符号ふごうなし整数せいすうがたデータれつがMD5である。
//リトルエンディアンでの出力しゅつりょく
md5[ 0.. 3] := split (a0, 8bit) ;
md5[ 4.. 7] := split (b0, 8bit) ;
md5[ 8..11] := split (c0, 8bit) ;
md5[12..15] := split (d0, 8bit) ;
end.

なお、RFC 1321 にある本来ほんらいしきえて、以下いかのように計算けいさんするほうが効率こうりつてき場合ばあいがある(高級こうきゅう言語げんごいている場合ばあい、コンパイラの最適さいてきまかせるほうがよい。 NANDとANDが並行へいこうして計算けいさんできる環境かんきょうであれば、並列へいれつ演算えんざんのできない以下いかしきくらべて、もとのままのほうがはやいことも多々たたある)。

( 0 ≦ i ≦ 15): F := D bitXor (B bitAnd (C bitXor D))
(16 ≦ i ≦ 31): F := C bitXor (D bitAnd (B bitXor C))

実装じっそうライブラリ

[編集へんしゅう]

MD5をサポートしているライブラリは以下いかとおり。

参考さんこう文献ぶんけん

[編集へんしゅう]
  • R. Rivest, "The MD5 Message-Digest Algorithm", RFC 1321, April 1992.
  • Hans Dobbertin, "The Status of MD5 After a Recent Attack", CryptoBytes Volume 2, Number 2, pp.1,3-6, Summer 1996. [1]
  • Xiaoyun Wang, Dengguo Feng, Xuejia Lai, Hongbo Yu, "Collisions for Hash Functions MD4, MD5, HAVAL-128 and RIPEMD", IACR ePrint #199, Augst 17 2004. [2]

脚注きゃくちゅう

[編集へんしゅう]

関連かんれん項目こうもく

[編集へんしゅう]

外部がいぶリンク

[編集へんしゅう]