Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What is going on with this article?

More than 3 years have passed since last update.

@managata

file archiver 'ezio' の暗号関係仕様

ezio の暗号化について

このドキュメントでは、ezio の暗号処理上の基本的な仕様を解説します。

ezio は、主に Linux/UNIX で動作するアーカイバですが、外部ツール(openssl や gpg)に依存せず、自前で暗号や署名を処理します。内部的には Go 言語が標準的に提供するライブラリを利用していますが、それらライブラリを正しく利用できているのかは、必ずしも検証されていません。

ezio の format

ezio は file を EZML format で encode します。EZML は、Matroska や WebM で採用されている EBML のサブセットとして設計されました(たとえば element type は master, binary, uint64 のみです)。EBML は XML のバイナリー版といわれることもあるフォーマットで、拡張が比較的に容易です。

ezio が file を暗号化すると、XML 風な表現をするなら、出力は以下のような構造となります。

<Ezml>
  <Suite>cipher algorithm</Suite>
  <KekSalt>random byte</KekSalt>
  <Nonce>random byte + counter^NonceMask</Nonce>
  <NonceMask>random byte</NonceMask>
  <Cek>encrypted CEK</Cek>
  <MetaData>encrypted metadata</MetaData>
  <Data>encrypted data chunk</Data>
  <Data>encrypted data chunk</Data>
  ...
  <MetaData>encrypted metadata</MetaData>
  <Eof>total size</Eof>
</Ezml>

ちなみに、暗号化しない場合は以下のように。

<Ezml>
  <Suite>cipher algorithm</Suite>
  <Path>filename</Path>
  <Type>file type</Type>
  <Size>file size</Size>
  ...
  <Data>data chunk</Data>
  <Data>data chunk</Data>
  ...
  <SizeEnc>encoded file size</SizeEnc>
  <Hash>file data hash</Hash>
  <HashMeta>metadata hash</HashMeta>
  <Eof>total size</Eof>
</Ezml>

ezio は、file ごとに以上のような構造へ encode した後、単純に archive file へ追記していきます。

ただし、archive の最後には、quick access 用の metadata list や、archive repairing 用の erasure code などの、特別なデータが付加されることがあります。しかし、それらは file の抽出に必要というわけではなく、個々の file は上記の構造で局所的に完結しています。

暗号化に関連する element

Suite

圧縮のアルゴリズムとともに、どの暗号のアルゴリズム(AES256-GCM もしくは CHACHA20-POLY1305)、Hash 関数(SHA256 もしくは SHA512)が使われているか、記録されています。

KekSalt

Go の crypto/rand.Read() によって生成された 32 もしくは 64 bytes の乱数です(以下、乱数は全て crypto/rand.Read() によります)。ユーザーが入力した password による対称鍵暗号を使用するモードでのみ、生成されます。

この salt と password を使い、sha256 もしくは sha512 の HKDF によって、KEK(Key Encryption Key) を生成します。

KekSalt は、言い換えると KEK は、1 つの archive の中の全ての file で共通であるように実装されていますが、そうしなければならない理由はありません。しかし file ごとに KEK を変更する必然性も(おそらく)ないはずです。

Nonce

AES256-GCM もしくは CHACHA20-POLY1305 で使用する 12 bytes の nonce(IV) の初期値です。

Nonce は、2 つの部分から構成されます。random part 4 bytes と counter part 8 bytes です。random part は crypt/rand.Read() によって生成された乱数です。counter part は、uint64 の counter と NonceMask の xor です。

MSB | 0| 1| 2| 3| 4| 5| 6| 7| 8| 9| 10| 11| LSB
    | random    | counter xor NonceMask   |

counter は、Nonce を暗号化/複合化で使うたびに +1 します。上記 XML 風表現の場合、Cek が最初の encrypted element ですが、その暗号化の際にはNonce の counter を increment して生成した nonce を使用し、次の MetaData の暗号化の際には、さらに increment したものを使うわけです。

encrypt された binary の先頭 12 bytes には、使用した nonce が埋め込まれています。復号の際には、埋め込まれた nonce と、Nonce を初期値として生成した nonce を比較して、一致していることを確認します。

nonce が counter によって生成されることから、1 つの file の暗号化において、同じ値の nonce が重複して使用されることはありません。また、archive 内の全ての file の暗号化においても nonce が unique となるよう、counter と NonceMask は次の file の処理へ持ち越します。

NonceMask

乱数 8 bytes です。

Cek

Cek element は、対称鍵暗号モードの場合は KEK を使った AES256-GCM/CHACHA20-POLY1305 によって、公開鍵暗号モードの場合は public key を使った RSA によって暗号化された CEK(Contents Encryption Key) です。

CEK そのものは、必要な大きさ(現時点では 32 bytes)の乱数です。

CEK は、KEK とは違って、file ごとに別の値をとります。このため、公開鍵暗号モードでは file ごとの RSA 秘密鍵での復号処理が重く、結果として archive の extract が非常に遅い問題を抱えています。(file data そのものを RSA で処理するのではなく、
あくまでも CEK のみ公開鍵暗号で処理するにも関わらず、かなり重いです)

なお、AES256-GCM や CHACHA20-POLY1305 で暗号化された binary は、先頭 12 bytes が nonce です。その後に暗号化された本体が続きます。そして最後に 16 bytes の tag が付加されています。

MetaData

MetaData element は encrypt された binary ですが、論理的には(XML 風に書くなら)以下のような構造をしています。

<MetaData>
  <Path>dir/name</Path>
  <Size>13539</Size>
</MetaData>

<Path>などの child element を EZML で encode した後に、すべてまとめた一塊の binary を、CEK と nonce を使って AES256-GCM/CHACHA20-POLY1305 で暗号化したものが、MetaData element の binary となります。

なお、MetaData は圧縮されません。

Data

Data は file の内容そのものです。圧縮する場合は、暗号化の前に行います。

AES256-GCM や CHACHA20-POLY1305 の処理上の都合により、(compressed) data は 16MiB 以下の大きさの chunk に分割されて、CEK と nonce を使って暗号化されます。
(暗号化されなくても必ず分割されます)

16MiB というサイズに論理的な根拠はなく、議論の余地があります。

参考リンク

0
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What is going on with this article?