Slide 1

Slide 1 text

MIMEと 文字コードの闇 Hornetsecurity株式会社 平野善隆

Slide 2

Slide 2 text

自己紹介 名前 平野 善隆 所属 Hornetsecurity株式会社 (Vade Japan 株式会社) Principal Messaging Engineer 文字コードとの関わり 1990年代前半に日本のPC通信上で ハングルを扱う環境を開発。 この過程で様々な文字コードを変換。 日本語の文字コード変換も開発 趣味 世界の長距離の自転車大会(1,200kmとか、2,000kmとか) バンド演奏 ドメイン調査

Slide 3

Slide 3 text

もくじ 3 • メールヘッダの読み方 • いにしえのインターネットでの日本語 • MIMEの登場 • 国際化ドメイン

Slide 4

Slide 4 text

基本的なヘッダ

Slide 5

Slide 5 text

メールソースの例 5 MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 27 Feb 2025 13:25:01 +0900 From: To: Subject: test Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit test

Slide 6

Slide 6 text

ヘッダの基本 6 • ヘッダ名: 内容 で構成される • 1つのヘッダは1行で表されている • 空行の前までがヘッダ MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 27 Feb 2025 13:25:01 +0900 From: To: Subject: test Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit test ここは本文

Slide 7

Slide 7 text

Message-ID 7 • このメールを特定する世界で1つのID • <○○@○○>の形式 • @の後ろはドメインが推奨される MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 27 Feb 2025 13:25:01 +0900 From: To: Subject: test Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit test

Slide 8

Slide 8 text

Date 8 • メールが送信された日時 • 曜日, 日 月 年 時:分:秒 タイムゾーン の形式 • 曜日はオプション MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 27 Feb 2025 13:25:01 +0900 From: To: Subject: test Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit test

Slide 9

Slide 9 text

From 9 • メールを送信した人 • 形式は display name <メールアドレス> など • envelope fromと同じである必要はない MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 27 Feb 2025 13:25:01 +0900 From: To: Subject: test Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit test

Slide 10

Slide 10 text

To 10 • メールの送信先 • 形式は display name <メールアドレス> など • envelope toと同じである必要はない MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 27 Feb 2025 13:25:01 +0900 From: To: Subject: test Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit test

Slide 11

Slide 11 text

From, To, Cc メールアドレスの形式 11 • To: [email protected] • To: • To: HIRANO など Display Name と呼びます

Slide 12

Slide 12 text

Subject 12 • 件名 MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 27 Feb 2025 13:25:01 +0900 From: To: Subject: test Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit test

Slide 13

Slide 13 text

本文 13 • CR/LF/CR/LFの後がBody MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 27 Feb 2025 13:25:01 +0900 From: To: Subject: test Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit test

Slide 14

Slide 14 text

ヘッダの折り返し 14 Subject: long long long long long long long long long long long long long long long subject To: [email protected], [email protected], [email protected], [email protected] • SMTPの1行の制限 = 998バイト • 78文字以下が望ましい • 長いヘッダは折り返す • 2行目以降はスペースやタブで始まる • 改行、スペースやタブの連続は 合わせて1つのスペースとみなされる スペース TAB

Slide 15

Slide 15 text

インターネットは7bit

Slide 16

Slide 16 text

日本語の扱い 16 Message-ID: <[email protected]> Date: Thu, 14 Nov 2019 15:00:01 +0900 From: HIRANO Yoshitaka To: Subject: ここは日本語です ここは日本語です • 7bitしか通らないので、7bitの文字コードを 使用する ここは日本語です = ESC$B$3$3$OF|K\8l$G$9ESC(B

Slide 17

Slide 17 text

アルファベットの文字コード(USASCII) 17

Slide 18

Slide 18 text

JIS X 0208 18 00-1F 20 21-7E 7F 80-FF 00-1F 未使用 未使用 未使用 未使用 未使用 20 未使用 未使用 未使用 未使用 未使用 21-7E 未使用 未使用 ここだけ 未使用 未使用 7F 未使用 未使用 未使用 未使用 未使用 80-FF 未使用 未使用 未使用 未使用 未使用 94 x 94 = 8836文字

Slide 19

Slide 19 text

JIS X 0201 19

Slide 20

Slide 20 text

ISO-2022-JP 20 • ESC ( B ➔ ASCII • ESC ( J ➔ JIS X 0201 • ESC $ @ ➔ JIS X 0208-1978 • ESC $ B ➔ JIS X 0208-1983 or 1990 ここは日本語です = ESC$B$3$3$OF|K\8l$G$9ESC(B

Slide 21

Slide 21 text

日本語の文字コード 21 • JIS X 0208 ≈ ISO-2022-JP • 7bitの文字コード • EUC-JP • JIS X 0208の8bit目を立てたもの • SHIFT_JIS • JIS X 0208をいい感じに移動したもの • 1byte目: 81~9F, E0~EF • 2byte目: 40~7E, 80~FC

Slide 22

Slide 22 text

EUC-JP 22 1バイト目 2バイト目 文字集合 内容 00-7F - ASCII (7bit) ASCII (7bit) A1-FE A1-FE JIS X 0208 JIS X 0208の8bit を立てたもの 8E A1-DF JIS X 0201 (半角かな) 半角かな 8F A1-FE JIS X 0212 (補助漢字) 拡張漢字

Slide 23

Slide 23 text

Shift_JIS 23 1バイト目 2バイト目 文字集合 内容 00-7F - ASCII (7bit) ASCII (7bit) A1-DF - JIS X 0201 (半角かな) 半角かな 80-9F, E0-EF 40-7E, 80-FC JIS X 0208 JISX0208を移動 したもの F0-FC 40-7E, 80-FC 闇の部分 Windowsの Shift_JISはここを 含む

Slide 24

Slide 24 text

え、ほかにも? 24 • ISO-2022-JP-2 • ISO-2022-JP-3 • MS932 • CP932 • ・・・見なかったことにしましょう

Slide 25

Slide 25 text

しかし現実は 25 • 件名にShift_JISがそのまま記述される • 特にスパムメール 一方韓国では? • EUC-KR (ks_c_5601)が主流

Slide 26

Slide 26 text

MIMEの登場

Slide 27

Slide 27 text

MIME-Version 27 MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 14 Nov 2019 15:00:01 +0900 From: To: Subject: test Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit test • ASCII以外のヘッダや本文を扱えるようにする • 添付ファイルを扱えるようにする • Content-○○ヘッダを使えるようにする

Slide 28

Slide 28 text

Content-Type 28 MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 14 Nov 2019 15:00:01 +0900 From: HIRANO Yoshitaka To: Subject: test Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit test • Bodyがどんな形式かを表す • MIME Type/MIME SubType; attribute=value のような形式

Slide 29

Slide 29 text

Content-Transfer-Encoding 29 MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 14 Nov 2019 15:00:01 +0900 From: HIRANO Yoshitaka To: Subject: test Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit test • Bodyのエンコード方式を表す • 7bit, 8bit, base64, quoted-printable など

Slide 30

Slide 30 text

日本語の扱い 30 MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 14 Nov 2019 15:00:01 +0900 From: HIRANO Yoshitaka To: Subject: =?ISO-2022-JP?B?GyRCJDMkMyRPRnxLXDhsJEckORsoQg==?= Content-Type: text/plain; charset=iso-2022-jp Content-Transfer-Encoding: 7bit ここは日本語です • MIMEエンコードを利用する ここは日本語です = ESC$B$3$3$OF|K\8l$G$9ESC(B

Slide 31

Slide 31 text

ヘッダのエンコード

Slide 32

Slide 32 text

ヘッダの日本語の扱い 32 • MIMEエンコードを利用する • =?文字コード?BまたはQ?エンコードされた文字列?= = ESC$B$3$3$OF|K\8l$G$9ESC(B =ここは日本語です =?ISO-2022-JP?B?GyRCJDMkMyRPRnxLXDhsJEckORsoQg==?= 文字コード B: BASE64 Q: Quoted Printable

Slide 33

Slide 33 text

BASE64とは 33 • あいう • E3 81 82 E3 81 84 E3 81 86 • 11100011 10000001 10000010 11000011 10000001 10000100 11100011 10000001 10000110 • 11100011 10000001 10000010 11000011 10000001 10000100 11100011 10000001 10000110 • 38 38 06 02 30 38 06 04 38 38 06 06

Slide 34

Slide 34 text

BASE64とは 34 • 38 38 06 02 30 38 06 04 38 38 06 06 • 56 56 6 2 48 56 6 4 56 56 6 6 • 44GCw4GE44GG Value Encoding Value Encoding Value Encoding Value Encoding 0 A 17 R 34 i 51 z 1 B 18 S 35 j 52 0 2 C 19 T 36 k 53 1 3 D 20 U 37 l 54 2 4 E 21 V 38 m 55 3 5 F 22 W 39 n 56 4 6 G 23 X 40 o 57 5 7 H 24 Y 41 p 58 6 8 I 25 Z 42 q 59 7 9 J 26 a 43 r 60 8 10 K 27 b 44 s 61 9 11 L 28 c 45 t 62 + 12 M 29 d 46 u 63 / 13 N 30 e 47 v 14 O 31 f 48 w (pad) = 15 P 32 g 49 x 16 Q 33 h 50 y 桁が4の倍数に ならない場合は=を追加する

Slide 35

Slide 35 text

ヘッダの日本語の扱い (BASE64) 35 • MIMEエンコードを利用する • BASE64の場合 = ESC$B$3$3$OF|K\8l$G$9ESC(B =ここは日本語です =?ISO-2022-JP?B?GyRCJDMkMyRPRnxLXDhsJEckORsoQg==?= 文字コード B: BASE64 GyRCJDMkMyRP ... 6 50 17 2 9 3 12 36 12 50 17 15 ...  BASE64の表を見ながら数字に直す(10進数) 06 32 11 02 09 03 0c 24 0c 32 11 0f ...  上の16進数表記 6bitの2進数表記↴ 000110 110010 010001 000010 001001 000011 001100 100100 001100 110010 010001 001111 ... 00011011 00100100 01000010 00100100 00110011 00100100 00110011 00100100 01001111 ... 1b 24 42 24 33 24 33 4f ...  16進数表記 ⇧8bitで区切り直す ESC $ B $ 3 $ 3 O ...

Slide 36

Slide 36 text

Quoted Printableとは 36 • あいう • E3 81 82 E3 81 84 E3 81 86 • =E3=81=82=E3=81=84=E3=81=86 • あabc • =E3=81=82abc

Slide 37

Slide 37 text

ヘッダの日本語の扱い (Quoted Printable) 37 • MIMEエンコードを利用する • Quoted Printableの場合 = ESC$B$3$3$OF|K\8l$G$9ESC(B =ここは日本語です 文字コード B: BASE64 Q: Quoted Printable =?ISO-2022-JP?Q?=1B$B$3$3$OF|K\8l$G$9=1B(B?=

Slide 38

Slide 38 text

“”で囲むかどうか 38 1 =?ISO-2022-JP?B?GyRCSj9MbiRHJDkbKEI=?= 2 "=?ISO-2022-JP?B?GyRCSj9MbiRHJDkbKEI=?=" An 'encoded-word' MUST NOT appear within a 'quoted-string'. RFC2047 本当は囲んでは いけない でも、わりと 囲まれている

Slide 39

Slide 39 text

スペースの扱い 39 • =?ISO-2022-JP?B?GyRCJCIbKEI=?==?ISO-2022-JP?B?GyRCJCQbKEI=?= ➔ あい • =?ISO-2022-JP?B?GyRCJCIbKEI=?=a=?ISO-2022-JP?B?GyRCJCQbKEI=?= ➔ あaい • =?ISO-2022-JP?B?GyRCJCIbKEI=?= a =?ISO-2022-JP?B?GyRCJCQbKEI=?= ➔ あ a い • =?ISO-2022-JP?B?GyRCJCIbKEI=?= =?ISO-2022-JP?B?GyRCJCQbKEI=?= ➔ あい • =?ISO-2022-JP?B?GyRCJCIbKEI=?= =?ISO-2022-JP?B?GyRCJCQbKEI=?= ➔ あい • =?ISO-2022-JP?B?GyRCJCIbKEI=?= =?ISO-2022-JP?B?GyRCJCQbKEI=?= ➔ あい • =?ISO-2022-JP?B?GyRCJCIbKEIgICAgIBskQiQkGyhC?= ➔ あ い

Slide 40

Slide 40 text

セキュリティリスク 40 =?utf-8?B?PGJhZGd1eUBiYWQuZXhhbXBsZS5jb20+LA== ➔ , ➔ [ {displayName=“”, addr=“[email protected]”}, {displayName=“”, addr=“[email protected]”} ] • もし、先に文字コードをdecodeしてしまうと

Slide 41

Slide 41 text

本文の エンコーディング

Slide 42

Slide 42 text

本文の日本語の扱い 42 MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 14 Nov 2019 15:00:01 +0900 From: HIRANO Yoshitaka To: Subject: Test Content-Type: text/plain; charset="iso-2022-jp" Content-Transfer-Encoding: 7bit ここは日本語です • MIMEエンコードを利用する • Content-Typeで文字コードを指定 ここは日本語です = ESC$B$3$3$OF|K\8l$G$9ESC(B

Slide 43

Slide 43 text

本文の日本語の扱い (BASE64) 43 MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 14 Nov 2019 15:00:01 +0900 From: HIRANO Yoshitaka To: Subject: Test Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: base64 44GT44GT44Gv5pel5pys6Kqe44Gn44GZ44CCDQo= • 本文にもMIMEエンコードを利用する

Slide 44

Slide 44 text

HTMLの文字コード 44 • HTMLも文字コードを指定できる MIME-Version: 1.0 Message-ID: <[email protected]> Date: Thu, 14 Nov 2019 15:00:01 +0900 From: HIRANO Yoshitaka To: Subject: Test Content-Type: text/html; charset="iso-2022-jp" Content-Transfer-Encoding: quoted-printable =1B$B$3$3$OF|K\8l$G$9=1B(B =1B  ESC =3D  =

Slide 45

Slide 45 text

現実のHTMLメールの闇 ① 45 Content-Type: text/html; charset="ISO-2022-JP" Content-Transfer-Encoding: quoted-printable =1B$B$8$c$i$sM7$S!&BN83=1B(B =1B$BNW;~A}4)9f=1B(B

Slide 46

Slide 46 text

現実のHTMLメールの闇 ② 46 Content-Type: text/html; charset="euc-jp" Content-Transfer-Encoding: 8bit "> 平野 善隆 様 ( [email protected] ) EUC-JP

Slide 47

Slide 47 text

URLエンコード 47 • あいう • E3 81 82 E3 81 84 E3 81 86 • %E3%81%82%E3%81%84%E3%81%86 • あabc • %E3%81%82abc

Slide 48

Slide 48 text

URLエンコード + HTMLメール 48 Content-Type: text/html; charset="iso-2022-jp" Content-Transfer-Encoding: quoted-printable =1B$B$3$3$OF|K\8l$G$9=1B(B Click here URLエンコード UTF-8

Slide 49

Slide 49 text

メール作成時の文字コード選択・判定 49 • メール作成時に文字コードは自動判定される • こんにちは ➔ iso-2022-jp • hello! ➔ us-ascii • 中国 ➔ iso-2022-jp? gb2312?

Slide 50

Slide 50 text

実際の文字化けの例 50

Slide 51

Slide 51 text

GB18030 GBK なぜ文字化けしたのか 51 • 日本語のメール(UTF-8)に返信 • 中国語だと判定したのか、 Content-TypeをGB2312に設定して送信 • しかし実際に送られた本文はGBK • 受信した環境はGB2312の範囲外の文字を削除 • 文字化け GB2312

Slide 52

Slide 52 text

添付ファイル

Slide 53

Slide 53 text

添付ファイル名のエンコード① 53 Content-Type: application/pdf; name="=?ISO-2022-JP?B?GyRCJS8lbCU4JUMlSCUrITwlSUxAOlkbKEIwMS5wZGY=?="; charset=ISO-2022-JP Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="=?ISO-2022-JP?B?GyRCJS8lbCU4JUMlSCUrITwlSUxAOlkbKEIwMS5wZGY=?=" クレジットカード明細01.pdf

Slide 54

Slide 54 text

添付ファイル名のエンコード② 54 Content-Type: application/vnd.ms-excel; name="=?ISO-2022-JP?B?GyRCOk5FQEQiSTw8QTU/MX5FehsoQl8wNDAyMTJfMDEoGyRCSj9MbhsoQikueGxz?=" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename*0*=ISO-2022-JP''%1B$B%3ANE%40D%22I%3C%3CA5%3F1~Ez%1B%28B; filename*1*=_040212_01%28; filename*2*=%1B$BJ%3FLn%1B%28B; filename*3*=%29.xls RFC2231 採点帳票質疑応答_040212_01(平野).xls

Slide 55

Slide 55 text

添付ファイルのエンコード 55 • BASE64でエンコード Content-Type: application/pdf; name="=?ISO-2022-JP?B?GyRCJS8lbCU4JUMlSCUrITwlSUxAOlkbKEIwMS5wZGY=?="; charset=ISO-2022-JP Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="=?ISO-2022-JP?B?GyRCJS8lbCU4JUMlSCUrITwlSUxAOlkbKEIwMS5wZGY=?="

Slide 56

Slide 56 text

UTF-7

Slide 57

Slide 57 text

IMAP フォルダ名のエンコード 57 修正UTF-7, mUTF-7 • 「&」以外の印字可能なUS-ASCII文字は必ずそのまま表記する。 • それ以外の文字はUTF-16のビッグエンディアンで符号化し、 修正BASE64で符号化する。 • BASE64の文字の前に「&」後ろに「-」を置く。 • 「&」の文字自体は「&-」で表現する。 folder ➔ folder こんにちはabc ➔ &MFMwkzBrMGEwbw-abc

Slide 58

Slide 58 text

UTF-8は 万能なのか?

Slide 59

Slide 59 text

UTF-8の仕組み 59 • 可変長 • ASCIIの範囲はそのまま表現される バイト数 1バイト目 2バイト目 3バイト目 4バイト目 1 00 – 7F 2 C2 – DF 80 – BF 3 E0 – EF 80 – BF 80 – BF 4 F0 – F4 80 – BF 80 – BF 80 – BF

Slide 60

Slide 60 text

日本語メールを処理するとは? 60 • 日本語のメールが表示できる • 日本語のメールを検索できる • 日本語のメールをフィルタできる

Slide 61

Slide 61 text

検索・フィルタでの問題点 61 • iso-2022-jp • ESC$B$3$3$OF|K\8l$G$9ESC(B (こんにちは) • Shift_JIS • 83 74 83 42 83 8b 83 5e (フィルタ) • EUC-JP • A4 B3 A4 B3 (ここ) $9で検索 Bで検索 海(B3 A4)で検索 UTF-8にはこの問題がない

Slide 62

Slide 62 text

正規化 62 • 「が」(Windows) ≠ 「が」(MAC) • 「e3 81 8c」≠ 「e3 81 8b e3 82 99」 • 「が」≠ 「か゛」 NFC: 結合可能な文字を可能な限り1つの文字に合成する (例: é は e + ´ ではなく é で表現) NFD: 可能な限り文字を分解する(例: é は e + ´ に分解) NFKC: NFCに加えて互換文字(例: ½ → 1/2)も正規化 NFKD: NFD + 互換文字の分解 https://unicode.org/reports/tr15/

Slide 63

Slide 63 text

Homoglyph Attack Generator 63 https://www.irongeek.com/homoglyph-attack-generator.php •ホモグリフ •ホモグラフドメイン

Slide 64

Slide 64 text

メールアドレスの 多言語化

Slide 65

Slide 65 text

国際化ドメイン(IDN)のエンコード 65 • Punycodeでエンコードする • ドメインのみ利用可能 • 既存システムがそのまま使える hirano@東京.日本 ➔ [email protected] NFCで正規化する

Slide 66

Slide 66 text

EAIとは 66 • Email Address Internationalization • メールアドレスのLocal Partも多言語化 • UTF-8を直接使う • ドメイン部分もUTF-8で表記し、裏でpunycodeを使用 • 既存のプロトコルに拡張が必要 • RFC5335 平野@東京.日本 NFCでの正規化が推奨 (必須とは言っていない) the use of normalization form NFC is RECOMMENDED.

Slide 67

Slide 67 text

EAIとホモグラフドメイン 67 • hirano@jρааѡɡ.org ➔ [email protected][email protected][email protected]

Slide 68

Slide 68 text

まとめ

Slide 69

Slide 69 text

まとめ 69 • MIMEが普及する前は混沌としていた • MIME普及後ましにはなったが、依然として様々 な文字コードが混在している • 例えUTF-8に統一したとしても問題はある • 国際化ドメインやEAIなどは、危険な香りしかし ない