GrapeCity Secure Mail for .NET 4.0J > メールプロトコルの概要 > MIME の概要 |
MIME(Multipurpose Internet Mail Extensions)は、RFC 822 の規定するテキストのみの形式では極めて制限が大きいために必要とされます。MIME は、メールメッセージにテキスト以外のデータを持たせることを可能にし、MIME 未対応のメールサーバーとも下位互換性を維持します。MIME は実装された当初、RFC 822 の規定する従来のメッセージ構造を一部変更しました。また、MIME コンテンツを指定するための、MIME 固有の追加ヘッダフィールドが要求されました。メッセージ本文の構造も、複数のファイル形式を受け入れられるように変更されました。最後に、ASCII 以外の添付データに対し、エンコードのルールが規定されました。この方法で MIME を実装すると、メール転送エージェントの仕様は変更しなくてもよく、送受信を行うクライアント側だけに、MIME 添付データを処理するための変更が必要となります。
RFC 822 のメール構造に追加されたメッセージヘッダフィールドは以下のとおりです。
MIME-Version | MIME 形式のバージョンを指定し、メッセージが MIME 構造であることを識別 |
Content-Description | メッセージコンテンツに関する追加情報 |
Content-ID | メッセージ識別子 |
Content-Transfer-Encoding | メッセージ部分に適用されるエンコードの種類。8ビットデータを7ビットデータに変換するために最も一般的に使用されるエンコード形式は、Base64 と Quoted-Printable の2つ |
Content-Type | メディアのタイプとサブタイプ |
以上のヘッダのうち、このトピックで特に注目するのは、「Content-Transfer-Encoding」および「Content-Type」の2つのヘッダフィールドです。
Content-Type は、メッセージ本文の特性(ファイルの種類)を指定します。RFC 1521 では、以下の7つのタイプが規定されています(現在も改訂中)。
このフィールドの目的は、受信側クライアントがパートのコンテンツを判別し、適切に処理できるようにすることです。上記7つのタイプにはそれぞれサブタイプがあり、そのデータタイプの特定のフォーマットを定義します。この機能を確認するために、MIME 対応のユーザーエージェントによって送信された ASCII テキストメッセージの各フィールドを検証します。
< RFC 822 ヘッダフィールドは省略 > Content-Transfer-Encoding: Quoted-Printable Content-Type: text/plain; charset=ISO-8859-1 MIME-Version: 1.0 < メッセージコンテンツ(ASCII テキストは省略) > |
この例では、MIME のバージョンが 1.0 であり、使用されたエンコード形式が Quoted-Printable(後述)であることが分かります。Content-Type は「text」であり、サブタイプは「plain」です。これは、フォーマットを何も適用しない ASCII テキストでメールが作成されていることを意味します。
次の例では、1つの画像のみを添付したメッセージの MIME ヘッダフィールドを検証します。
< RFC 822 ヘッダフィールドは省略 > MIME-Version: 1.0 Content-Type: image/gif; name="Dart.GIF" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="Dart.GIF" < エンコードされたメッセージは省略 > |
ここでも MIME バージョンは 1.0 ですが、使用されたエンコード形式は Base64 です。Content-Type は「image」、サブタイプは「gif」であり、受信側のユーザーエージェントに Dart.GIF ファイルが実際に「gif」タイプの画像であることを通知しています。
次は、Content-Transfer-Encoding ヘッダフィールドを検証します。
前述のとおり、Content-Transfer-Encoding ヘッダフィールドは使用された MIME エンコードの種類を通知します。これにより、受信側クライアントは、このデータを送信側と同じ方法を用いて適切にデコードできるようになります。MIME メッセージはなぜエンコードの必要があるのでしょうか?ほとんどのファイル形式は、通常の状態で8ビットファイルとなります。残念ながら SMTP プロトコルでは、メッセージが7ビットに制限されています。これは、SMTP が本来、7ビットの ASCII テキストだけを転送するように実装されたためです。メール配信に対応できるようにエンコードを行う場合、まず8ビットファイルを基に、エンコードアルゴリズムを使用して7ビットファイルを作成し、すべての SMTP エージェントとの互換性を確保します。
具体的には、どのように機能するのでしょうか。RFC 2045 では、Quoted-Printable および Base64 の2つのアルゴリズムの使用を定義しています。この2つのスキームと Content-Type ヘッダフィールドとの間には、定義できる関係は存在しません。つまり、同じファイル形式が常に同じスキームによってエンコードされるわけではないことを意味します。
Quoted-Printable エンコードシステムは、次のように機能します。8ビット文字には、有効な組み合わせが 256 通り(2^8)あります。このうち 128(2^7)が、印刷可能な ASCII 文字(7ビット文字)です。この7ビット文字については、転送上の問題はありません。ここで必要となるのは、残りの 256-128 文字(8ビットで表される文字)についての処理方法です。これには、この文字を 16 進数の値として引用します。たとえば、値 200 の文字は「=C8」としてエンコードされます。
Quoted-Printable によるエンコードデータは、行指向であることが前提です。実際には、ASCII 文字が元の形式を維持するため、Quoted-Printable でエンコードしたファイルはかなり読みやすいものとなります。このエンコードシステムを使用すると、各行は 76 文字未満の長さで転送されます。
このアルゴリズムの仕組みを確認するため、Quoted-Printable エンコードによる次のデータを検証します。
<!doctype HTML public "-//W3C//DTD HTML 4.0 Frameset//EN"> <html> <!--(=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D)--> <!--(Document created with RoboEditor. )=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D--> <!--(=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D)--> <head> <title>Tutorial</title> |
ASCII 文字によるいくつかのタグが残されているため、この文書が HTML ページの一部であることが分かります。この他、エンコードされた多量の文字が含まれています。これらの文字には、前に「=」が付いているので明確に区別できます。
Base64 によるエンコードは、Quoted-Printable によるエンコードとはまったく異なります。Base64 では、エンコード後のデータを人間が読めるようにする試みはいっさい行われません。また、このエンコード形式では、エンコード後のデータが元のデータより 33% 大きくなります。このスキームの動作は次のとおりです。まず、データが 24 ビットのグループに分割されます。データの元の形式では、1つのグループが3つの8ビットセグメントを表します。しかし、使用できるデータは7ビットに制限されているため、このグループを4つの6ビットセグメントにエンコードします。
このアルゴリズムの仕組みを確認するため、Base64 エンコードによる次のデータを検証します。
pcEATSAJBAAA8BK/AAAAAAAAEAAAAAAABAAAnRsAAA4AYmpiauI94j0AAAAAAAAAAAAAAAAAAAAA AAAJBBYAIjgAAIBXAACAVwAAnRcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//w8AAAAA AAAAAAD//w8AAAAAAAAAAAD//w8AAAAAAAAAAAAAAAAAAAAAAGwAAAAAACABAAAAAAAAIAEAACAB AAAAAAAAIAEAAAAAAAAgAQAAAAAAACABAAAAAAAAIAEAABQAAAAAAAAAAAAAADQBAAAAAAAAeAkA AAAAAAB4CQAAAAAAAHgJAAAAAAAAeAkAAAwAAACECQAAJAAAADQBAAAAAAAAA1UAAGgBAAC0CQAA AAAAALQJAAAAAAAAtAkAAAAAAAC0CQAAAAAAALQJAAAAAAAAtAkAAAAAAAC0CQAAAAAAALQJAAAA AAAAglQAAAIAAACEVAAAAAAAAIRUAAAAAAAAhFQAAAAAAACEVAAAAAAAAIRUAAAAAAAAhFQAACQA AABrVgAAIAIAAItYAAB8AAAAqFQAABUAAAAAAAAAAAAAAAAAAAAAAAAAIAEAAAAAAAC0CQAAAAAA |
データ構造が完全に変更されるため、エンコード後のデータは読解不可能です。次は、Content-Type ヘッダフィールドの Mulitpart タイプに焦点を当て、1つのメッセージ内に複数のパートが存在する場合の処理方法について説明します。
MIME では、複数のパートを使用できます。ここで、パートと添付データを区別する必要があります。添付データは常にパートですが、パートが常に添付データであるわけではありません。たとえば、テキストメールにファイルを添付して送信する場合、テキストと添付ファイルの2つのパートを作成することになります。
何らかのファイルをメッセージに添付すると、メインヘッダ内の Content-Type は multipart となり、メッセージテキスト以外にも他のパートが含まれることを示します。これらのパートはメインヘッダの後に列挙され、各パート間には自動的に区切り記号が生成されます。個々のパートが、それぞれ別のエンコードスキームによってエンコードされることもあります。これを確認するため、テキスト、gif ファイル、および Word 文書によって構成される次のメッセージを検証します。
メッセージ先頭にはヘッダが入ります。
Return-Path: <test@test.com> Received: from YOURCOMPUTER ([192.168.0.00]) by yourserver.com (Post.Office MTA v3.5 release 215 ID# 0-54045U100L2S100V35) with ESMTP id com for <test@email.com>; Fri, 2 Feb 2001 11:09:42 -0500 To: test@email.com From: test@test.com Subject: multipart email MIME-Version: 1.0 Content-Type: multipart/mixed; Boundary="--PTCP_00011cb405020407d1" Message-ID: <00011cb505020507d1@[192.168.0.71]> Date: Fri, 02 Feb 2001 11:10:35 -0500 |
当然ながら、従来の RFC 822 仕様のフィールドもすべて存在しますが、この例では Content-Type ヘッダに注目します。このタイプは multipart/mixed と示されているので、メインヘッダの後にいくつかの独立したパートが含まれることが予想できます。Boundary は、これらのパートが「--PTCP_00011cb405020407d1」という文字列によって区切られることを示します。これは、残りのメッセージ部分で簡単に確認できます。
----PTCP_00011cb405020407d1 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: Quoted-Printable This message is a multipart MIME test. ----PTCP_00011cb405020407d1 Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="Dart.GIF" Content-Type: application/octet-stream; name="Dart.GIF" R0lGODlhbwAmAPf/AP///xAQECEhISkpKTExMTk5OUJCQkpKSlJSUlpaWmNjY2tra3Nzc3t7e4SE hIyMjJSUlJycnKWlpa2trbW1tb29vcbGxs7OztbW1t7e3ufn5+/v7/f39+fe3tbGxrWcnGMxMVIA < 他の Base64 エンコードは省略 > ----PTCP_00011cb405020407d1 Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="dart site report.doc" Content-Type: application/msword; name="dart site report.doc" 0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAAKAAAAhwQAAAAAAAAA EAAAiQQAAAEAAAD+////AAAAAH0EAAB+BAAAfwQAAIAEAACBBAAAggQAAIMEAACEBAAAhQQAAIYE < 他の Base64 エンコードは省略 > ----PTCP_00011cb405020407d1-- |
3つの MIME パートは、前述の Boundary 文字列によって区切られているので簡単に区別できます。最初のパートはプレーンテキストによるメッセージです。これは Quoted-Printable によってエンコードされていますが、もともと ASCII 文字であるため、「This message is a multipart MIME test.」のままで変更はありません。
2番目のパートは、画像「Dart.GIF」として識別されています。予想されるようにこのパートは Base64 スキームによってエンコードされ、エンコード後のデータは人間には読めない意味不明の値の集合です。
3番目のパートは、「dart site report.doc」という Microsoft Word 文書として識別されています。ここでも、エンコードには Base64 が使用されています。メッセージは、最後の Boundary 文字列で終了します。