暗号技術の研究
最近、ぼちぼち、やってます。
とりあえず、以下の技術をC++で書くことができました。
これで、CMS(暗号メッセージ構文)で標準化されているフォーマットで、
パスワードを用いた暗号文を生成するプログラムが書ける!
●暗号関数
・DES
・T-DES
・AES
●ハッシュ関数
・SHA-1
・SHA-224
・SHA-256
●鍵付きハッシュ関数
・HMAC
●鍵導出関数
・PBKDF2
さて、世の中の暗号化のフリーソフトを見てみると、全然、規格に沿って無く、ある暗号文攻撃方法に弱いのではないか?と思うのです。
例えば、とあるソフトでは、パスワードをハッシュ関数を1000回通した値をそのままコンテンツ暗号化鍵に使用しています。初期化ベクターも0固定です。
つまり、あるパスワードを入力すると、生成されるコンテンツ暗号鍵が同一になり、初期化ベクターも0固定なため、同一のファイルと、同一のパスワードで暗号化すると、必ず同じ暗号文が生成されるわけです。
まず、パスワードで暗号鍵が同じになってしまう事については、辞書攻撃の耐性がなさそうです。
英語の辞書をかたっぱしから試したり、誕生日として想定される辞書を試したり。
つまり、暗号文を攻撃するプログラムが仕込まれたウイルスを作って、感染したコンピュータで一斉に暗号文攻撃をすれば、比較的早く、暗号文の攻撃が出来てしまいそうです。
そういった暗号攻撃にも耐性を持つためにも、CMSで規定されたパスワードによる暗号メッセージ構文は、非常に多くの乱数(暗号論的疑似乱数生成器等)を使います。暗号化のプロセスは、以下の通りです。
(1) コンテンツ暗号化鍵を、乱数で生成する。
(2) 初期化ベクタIVを、乱数で生成する。
(3) コンテンツを、乱数から生成した鍵で暗号化する。
(4) 入力されたパスワードから、鍵暗号化用の暗号鍵を導出する。
推奨される鍵導出関数"PBKDF2"のパラメータは
・HMAC関数へのSaltは、乱数で生成する。
・繰り返し回数は1000回が推奨。
・HMAC関数は、デフォルトではHMAC with SHA-1
(5) コンテンツ暗号鍵をラップ(暗号化)する。
デフォルトの"PWRI-KEK"では、
・初期化ベクタIVは、乱数で生成する。
・パディングデータも、乱数で生成する。
・『チェック用のヘッダー、コンテンツ暗号化鍵、パディング』を、パスワードから導出した暗号鍵で”2回”暗号化する。
といった手順を踏みます。
暗号メッセージ構文(暗号ファイル中)には、どういった内容が含まれるかというと、
・受信者情報(これは、パスワードを使ったという情報が記録される)
・どの鍵導出関数を使ったか(以下、PBKDF2のパラメータ)
・Salt(乱数で生成された)
・繰り返し回数(推奨は1000)
・使用するHMAC関数(デフォルトはHMAC with SHA-1)
・鍵ラップの方法(以下、PWRI-KEKのパラメータ)
・コンテンツ暗号化鍵を暗号化すした暗号について(以下、パラメータ)
・その初期化ベクタIV(乱数で生成された)
・ラッピング(暗号化)された、コンテンツ暗号化鍵
・暗号文情報
・コンテンツを暗号化した暗号について(以下、パラメータ)
・その初期化ベクタIV(乱数で生成された)
・暗号文本体
と、多くの情報が含まれることになる。
コンテンツの暗号化の暗号鍵は暗号論的疑似乱数生成器で生成するので、直接の辞書攻撃はまず不可能になる。
また、パスワードから鍵導出するにしても、同じパスワードを使用しても、Saltによって同一の暗号鍵が生成されることは無いので、辞書攻撃に掛かる時間ははるかに膨大となる。
Saltは、暗号化データの中には含めず、他の媒体とすることもできる。
この場合は、Saltが判明しない限りは、鍵導出は不可能になる。
つまり、パスワードと、他媒体に記録されたSaltが無いと、暗号文の復号はまず不可能になる
(軍事用途などで、機密文書をパスワードだけが解っても解読されないようにしたい場合のものだと思う。)
これが、RFCやPKCS、ITU等で規定された規格に準拠する暗号のファイルフォーマット。
(ASN.1でエンコードしないといけないので、またこれも、ヤヤコシイ。)
| 固定リンク


コメント