Punycodeとは?日本語ドメインがxn--に変換される仕組みを解説
- 1 「日本語.jp」は、DNSの中でも本当に日本語なのでしょうか
- 2 そもそもIDNとは何でしょうか
- 3 では、日本語をそのままDNSへ送ればよいのでしょうか
- 4 人間が見る文字と、DNSで使う文字を分ける
- 5 ではPunycodeとは何なのでしょうか
- 6 「xn--」は何を意味しているのでしょうか
- 7 IDNAとPunycodeは同じものではありません
- 8 ブラウザーでは何が起きているのでしょうか
- 9 それなら、なぜ普段はxn--が見えないのでしょうか
- 10 では、なぜ時々xn--がそのまま表示されるのでしょうか
- 11 日本語ドメインは「日本語を英語へ翻訳している」のではありません
- 12 どんなUnicode文字でも使えるわけではありません
- 13 TLDそのものが日本語になることもあります
- 14 Punycodeがあるから、昔のDNSを捨てずに多言語化できた
- 15 しかし「人間には日本語に見える」ことが別の問題を生みます
「日本語.jp」は、DNSの中でも本当に日本語なのでしょうか
前回は、日本語ドメインのメリットとデメリットを見てきました。その中で少し不思議な文字列が登場しました。ブラウザーでは「ドメイン名例.jp」と表示されているのに、ある場所では「xn--eckwd4c7cu47r2wf.jp」と表示されることがあります。初めて見ると、まったく別のドメインに変わってしまったように感じるかもしれません。しかし、この二つは同じドメインです。JPRSも「ドメイン名例.JP」と「XN–ECKWD4C7CU47R2WF.JP」を同じ日本語JPドメイン名の例として案内しています。
では、なぜ二つの表記が必要なのでしょうか。
ここに、日本語ドメインを支えているIDN、IDNA、Punycodeという仕組みがあります。

そもそもIDNとは何でしょうか
IDNはInternationalized Domain Name、国際化ドメイン名の略です。
従来のドメイン名では、主に英字、数字、ハイフンといったASCIIで表現できる文字が使われてきました。しかしインターネットが世界中へ広がれば、「自分たちの言語や文字でもドメイン名を使いたい」という要求が出てきます。日本語だけではありません。中国語、アラビア語、キリル文字、デーヴァナーガリー文字など、世界にはASCIIだけでは表せない文字が大量にあります。
そこで登場したのがIDNです。ICANNも、IDNによって世界中の利用者が自分たちの言語や文字体系をドメイン名に使えるようになると説明しています。
では、日本語をそのままDNSへ送ればよいのでしょうか
ここで問題が出てきます。
インターネットには、IDNが登場するよりはるか前からDNSがあります。もし「今日からDNSそのものを全部Unicode対応に作り直します」とすれば、世界中のサーバー、ソフトウェア、ネットワーク機器、アプリケーションに影響が出ます。そこで考えられたのが、既存の仕組みをできるだけ変えずに、アプリケーション側で日本語などをASCII表記へ変換して使う方法です。つまり日本語ドメインは、「DNS全体を日本語対応に作り替えた」のではなく、「既存のDNSで扱える形へ変換する層を追加した」と考えると分かりやすいでしょう。
人間が見る文字と、DNSで使う文字を分ける
IDNでは、同じドメイン名に二つの表現があります。
| 呼び方 | 例 | 役割 |
|---|---|---|
| U-label | ドメイン名例 | Unicodeを使った、人間が読める表記 |
| A-label | xn--eckwd4c7cu47r2wf | ASCIIだけで表した互換形式 |
U-labelの「U」はUnicodeをイメージすると分かりやすいでしょう。日本語、漢字、ひらがな、カタカナなど、人間が普段使っている文字をそのまま表現します。
一方のA-labelはASCII互換形式です。
JPRSは「ドメイン名例」というU-labelに対応するA-labelとして「xn--eckwd4c7cu47r2wf」を示しています。見た目はまったく違いますが、同じドメイン名を二つの方法で表しているだけです。
ではPunycodeとは何なのでしょうか
Punycodeは、Unicode文字列をASCII文字だけで表現するための符号化方式です。
例えば日本語の「ドメイン名例」を、一定の規則に従ってASCII形式へ変換すると、Punycodeによる文字列が得られます。そして、その前に「xn--」という接頭辞を付けることで、A-labelになります。つまり、ざっくり書けば、
ドメイン名例
↓ Punycodeで変換
eckwd4c7cu47r2wf
↓ IDNであることを示す接頭辞を付ける
xn--eckwd4c7cu47r2wf
という関係です。
補足:Punycodeは暗号ではありません
「xn--」から始まる文字列を見ると、暗号化されたように見えるかもしれません。しかしPunycodeは暗号ではありません。
一定の規則による符号化であり、元のUnicode文字列へ戻すことができます。JPRSも、PunycodeをUnicode文字列からASCII文字列へ一意かつ可逆的に変換する方式と説明しています。
「xn--」は何を意味しているのでしょうか
では、なぜ必ず「xn--」のような奇妙な文字から始まるのでしょう。
これはACE prefix、ASCII Compatible Encodingの接頭辞です。要するに「この文字列は普通の英数字ドメインではなく、国際化ドメイン名をASCII形式へ変換したものです」と識別するための目印です。例えば、
example
という普通のASCIIラベルと、
xn--eckwd4c7cu47r2wf
というA-labelを、ソフトウェアが区別できます。
「xn--」自体に日本語の意味があるわけではありません。
IDNAとPunycodeは同じものではありません
ここは少し混同されやすいところです。
日本語ドメインについて調べると、「IDN」「IDNA」「Punycode」という言葉がまとめて出てきます。
しかし同じものではありません。
| 用語 | ざっくりした意味 |
|---|---|
| IDN | 日本語などASCII以外の文字を含む国際化ドメイン名そのもの |
| IDNA | IDNをアプリケーションでどう扱うかを定めた仕組み・規格 |
| Punycode | Unicode文字列をASCII形式へ符号化するアルゴリズム |
IDNAはInternationalized Domain Names in Applicationsの略です。
名前の通り、ブラウザーなどのアプリケーションが国際化ドメイン名を扱うための仕組みです。
Punycodeは、その中で文字列をASCIIへ変換するために利用されます。現在の標準体系は一般にIDNA2008と呼ばれ、以前のIDNA2003を更新したものです。ただしPunycodeのアルゴリズム自体は引き続き利用されています。
ブラウザーでは何が起きているのでしょうか
では実際に、ブラウザーへ「ドメイン名例.jp」と入力したときの流れを簡略化して考えてみます。
- 利用者が「ドメイン名例.jp」と入力する
- ブラウザーなどのアプリケーションがIDNとして処理する
- 「ドメイン名例」の部分をA-labelへ変換する
- 「xn--eckwd4c7cu47r2wf.jp」というASCII互換形式になる
- その形式を使ってDNSの名前解決を行う
- 得られたIPアドレスへ接続する
利用者は日本語を入力していますが、その裏側では既存のDNSと互換性のある文字列へ変換されているわけです。これによって、世界中のDNSサーバーを日本語専用に作り直さなくても、日本語ドメインを利用できます。
それなら、なぜ普段はxn--が見えないのでしょうか
理由は単純です。
人間にとって、日本語で表示した方が分かりやすいからです。
「xn--eckwd4c7cu47r2wf.jp」と表示されても、何のサイトなのかほとんど分かりません。「ドメイン名例.jp」と表示されれば、少なくとも日本語として読むことができます。そのため対応したブラウザーなどは、内部ではA-labelを扱いながら、画面上ではU-labelを表示することがあります。つまり、Punycodeは本来ユーザーに読ませるための名前ではありません。人間に見せる名前と、既存システムと互換性を保つための名前を橋渡しする存在です。
では、なぜ時々xn--がそのまま表示されるのでしょうか
ここが少し重要です。
すべての場面で必ず日本語表示になるわけではありません。
アプリケーション、ログ、メールヘッダー、サーバー設定画面、証明書関連の情報、データベースなどでは、A-labelがそのまま表示される場合があります。また、ブラウザーなどが安全上の理由からUnicode表示を避け、Punycode表記を表示する場合もあります。ですから日本語ドメインを運用する場合には、自分のドメインのPunycode表記も知っておくと役に立ちます。
サーバー設定や障害調査で突然「xn--」が出てきても、「別のドメインになった」と慌てずに済みます。
日本語ドメインは「日本語を英語へ翻訳している」のではありません
ここにも誤解が起きやすいところがあります。
Punycodeは、日本語を英語へ翻訳しているわけではありません。例えば「東京」を「tokyo」に変換する仕組みではありません。「東京」というUnicode文字列そのものを、決められた方法でASCII文字列に符号化します。ですから意味の翻訳ではなく、文字表現の変換です。これはローマ字変換とも違います。
日本語が読めない人がPunycodeを見ても、元の意味が分かるわけではありません。
どんなUnicode文字でも使えるわけではありません
ではUnicodeに存在する文字なら、何でもドメイン名にできるのでしょうか。
そうではありません。
IDNでは、プロトコル上利用できる文字にルールがあります。さらに、それぞれのレジストリが「このTLDではどの文字を登録可能にするか」という文字テーブルや登録ポリシーを設けています。例えば日本語JPドメインについては、JPRSが利用できる日本語文字を定めています。またIANAには、各レジストリが使用するIDN文字テーブルを掲載するRepository of IDN Practicesがあります。
つまり「Unicodeで表現できる」ことと、「そのドメインとして登録できる」ことは別です。
TLDそのものが日本語になることもあります
ここまで「日本語.jp」のように、点の左側が日本語の例を見てきました。
しかしIDNは、左側だけの話ではありません。トップレベルドメインそのものが国際化されることもあります。
例えばIANAのRoot Zone Databaseには「.みんな」というgTLDが正式に登録されています。
人間には「.みんな」と見えますが、IANAのWHOISではASCII互換形式として「XN–Q9JYB4C」も示されています。
つまり、
example.みんな
のように、TLD側まで日本語になる仕組みも既にDNSルートへ導入されています。
国際化ドメインは「日本語.jp」という特殊な付け足しではなく、DNSの階層そのものを多言語化する仕組みにまで広がっているわけです。
Punycodeがあるから、昔のDNSを捨てずに多言語化できた
ここまでの仕組みを見ると、Punycodeは少し回りくどく感じるかもしれません。最初からDNSをUnicode対応にしてしまえばよかったのではないか、と考えたくなります。しかしインターネットでは、既に世界中で動いている仕組みを一斉に置き換えることは簡単ではありません。
IDNAとPunycodeの重要なところは、既存のDNSとの互換性を保ちながら、新しい文字体系を使えるようにしたことです。つまり、新しい世界を作るために古い仕組みを全部捨てたのではなく、間に変換層を作った。これはインターネットの技術ではよく見られる考え方でもあります。
しかし「人間には日本語に見える」ことが別の問題を生みます
ここまではPunycodeの便利さを見てきました。
日本語、中国語、アラビア語などを使えるようになり、世界中の利用者が自分の文字でドメイン名を使える。これは大きなメリットです。一方で、Unicodeには非常に多くの文字があります。そして中には、別の文字なのに人間の目にはほとんど同じように見えるものがあります。例えばラテン文字、キリル文字、ギリシャ文字などには、見た目が似ている文字があります。コンピューターにとっては別の文字なので別のドメインですが、人間には同じ名前に見えることがあります。
ここから、フィッシングやなりすましに悪用される可能性が生まれます。
だからブラウザーが、場合によっては日本語やUnicode表記ではなく、あえて「xn--」から始まるPunycodeを表示することもあるのです。Punycode自体が危険なのではありません。むしろ問題になるのは、人間の目が「似ている文字」を同じものだと判断してしまうことです。
次回は、この仕組みを悪用したホモグラフ攻撃について見ていきます。