forensic と日本語を含むメール

…という題で日記を書くと、人が釣れるらしい*1
とあるMLからの話題。私は forensic とは無縁なので、かなりの点を推測で書いています。

forensic では当然のことながら電子メールの調査も実施するのだろうと思います。現在、国内でのメールのほとんどは

Content-Type: text/plain; charset=ISO-2022-JP
Content-Transfer-Encoding: 7bit

なのだろうと思います*2
扱っているソフトにもよるのですが、このようなメールをファイルに保存した場合、ファイル上でのエンコーディングISO-2022-JP となるかも知れませんし、もしかすると Shift_JIS のような、より OS ネイティブなエンコーディングになるかも知れません。
これらのファイルを含む、 dd などで作成されたイメージから文字列を抽出するには、jstrings が役に立つのだろうと思います。

もちろん、1文字を複数バイトで表現する MBCS(Multi Byte Char Set) においては、文字の途中でセクタをまたぐ場合などの考慮は必要です*3。このあたりについては、forensic が本職の方に伺ってみましょう。

さて、電子メールの文字コード

Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: base64

になった場合はどうでしょうか。

ファイル上に保存した場合にも UTF-8base64エンコードした状態で記録されているかも知れません。ここから果たして日本語を探すことができるのでしょうか。
base64 では、8ビット×3の24ビットを、6ビット×4に分割し、0〜63に A〜Z、a〜z、0〜9 と +、/ の64文字を割り当てて符号化しています。

XXXXXXXX YYYYYYYY ZZZZZZZZ            もとの文字列(3バイトごと)
            ↓                         
00XXXXXX 00XXYYYY 00YYYYZZ 00ZZZZZZ   0〜63 の6ビット×4に分割
            ↓
0〜63 を A〜Z、a〜z、0〜9 と +、/ に割り当てる。

UTF-8 での "あいうえお" という文字列を例にとってみてみます。

 e3 81 82 e3 81 84 e3 81 86 e3 81 88 e3 81 8a ← "あいうえお" の UTF-8でのバイト列

これを base64エンコードすると

44GC44GE44GG44GI44GKDQo=

となります。繰り返しになりますが、base64エンコードされた結果は、A〜Z、a〜z、0〜9 と +、/ の64文字ですので、まずは strings を使って ascii 文字集合を抽出し、出てきた文字列から base64 らしきものをデコードする、という手順になるのでしょう。

ここで、先頭の"4"が喪失してしまった場合、base64をデコードすると、

` a8a b8b

という、まったく意味の取れない文字列になってしまいます。1バイト抜けた時点でまったくデコードできなくなってしまうのです。同様に、先頭に1バイト余分なゴミが混入しただけで、デコードできなくなってしまいます。

なんとも、forensic とは難しい仕事だと思ったりするわけです。そして、電子メールの残骸を漁るのに、jstrings での UTF-8 対応は必ずしも必要ではないのかもしれない、とも思ったわけです。

*1:一本釣り?

*2:text/htmlについてはここではいったん置いておきます

*3:http://www.st.ryukoku.ac.jp/~kjm/security/ml-archive/port139/2003.05/msg00175.html