Punycode 轉換(國際化域名)

將包含日語等非 ASCII 字元的國際化域名(IDN)與 Punycode(ASCII 相容編碼)相互轉換。

Punycode 是什麼

DNS 在歷史上只能處理 ASCII 字元。然而人們希望使用像「日本語.jp」這樣含有漢字與假名的網域名稱,為此搭起橋梁的便是 Punycode(RFC 3492)。它把 Unicode 字串可逆地轉換為以 xn-- 開頭的 ASCII 字串,從而在不改動既有 DNS 的前提下實現國際化網域名稱(IDN)。

轉換結果對人而言不可讀,這正是設計使然:日本語.jp 會變成 xn--wgv71a119e.jp。瀏覽器的網址列會隱去轉換後的樣貌,改以原本的文字顯示,因此平時並不會意識到它的存在。但這種外觀上的落差也是可被釣魚攻擊利用的弱點——用西里爾字母「а」冒充拉丁字母「a」之類難以分辨的字元來偽造網域,已經造成過實際的麻煩。本工具可進行雙向轉換,所有處理都在瀏覽器內完成。

轉換的步驟

  1. 選擇轉換的方向 在「網域名稱→Punycode」與「Punycode→網域名稱」之間擇一。
  2. 輸入網域名稱 請連同頂級網域一併輸入,如 日本語.jp。
  3. 查看結果 會顯示以 xn-- 開頭的轉換結果,或還原後的原始文字。
  4. 對照確認 藉由轉換後的 ASCII 表示,可確認是否混入了容易混淆的字元。

用好本工具的小技巧

  • 由多個標籤(以 . 分隔的部分)組成的域名也會按標籤自動判斷並轉換:僅含 ASCII 字元的標籤保持不變,只有包含非 ASCII 字元的標籤才會轉換為帶 xn-- 字首的形式。
  • 在「域名 → Punycode」模式下,會進行與 IDNA 相同的預處理:大寫字母轉為小寫,全形英文字母和數字轉為半形,全形的「。」「.」也作為標籤分隔符處理。例如,Bücher.de 會轉換為 xn--bcher-kva.de,例え。テスト 會轉換為 xn--r8jz45g.xn--zckzah。
  • 在"Punycode → 域名"模式下,只有包含 xn-- 字首的標籤會被解碼,其餘標籤將原樣保留。
  • 該轉換邏輯不僅適用於域名,也可應用於郵箱地址中 @ 之後的部分(域名部分)。
  • 在瀏覽器位址列中實際輸入國際化域名時,大多數瀏覽器會在內部先轉換為 Punycode,然後再進行 DNS 解析。

這些情境會用到

註冊或設定中文、日文網域

DNS 區域檔與伺服器憑證有時需要 Punycode 表示。

確認郵件的寄件者

顯示名看似正規,換算成 Punycode 後卻是另一個網域——這樣的案例確實存在。

解讀日誌中出現的 xn--

可查出存取日誌或報表中出現的 xn-- 字串究竟指向何處。

檢驗設定檔

可用於確認 nginx 或 Apache 的設定中能否直接書寫國際化網域名稱。

Punycode 的術語

Punycode
把 Unicode 字串可逆地轉換為 ASCII 字串的方式(RFC 3492)。xn-- 並不包含在 Punycode 的輸出中,而是用於域名時由 IDNA 在開頭加上的字首。
IDN(國際化網域名稱)
含有非 ASCII 字元的網域名稱。在內部會被轉換為 Punycode 以通過 DNS。
xn--
標示該標籤經 Punycode 編碼的前綴,稱為 ACE 前綴。
標籤
網域名稱以點分隔的各個部分。轉換是逐個標籤進行的。
同形異義字攻擊
以外觀極為相似的其他字元偽造網域的手法。換算成 Punycode 表示便可識破。
IDNA
為在 DNS 中處理 IDN 而制定的一系列規範,現行為 IDNA2008(RFC 5890 之後)。

常見問題

Punycode(RFC 3492)是一種編碼方式,用於將包含日語、中文、阿拉伯語等 Unicode 字元的域名(即國際化域名,IDN)轉換為 DNS 能夠處理的純 ASCII 字串。轉換後的標籤會帶有 xn-- 字首。

DNS(域名系統)最初的設計只考慮了 ASCII 字元,因此包含日語字元或表情符號的域名無法直接被解析。Punycode 通過將含非 ASCII 字元的域名轉換為 ASCII 字串,使得在完全不改變現有 DNS 基礎設施的前提下實現國際化域名成為可能。

xn-- 被稱為"ACE 字首"(ASCII Compatible Encoding prefix,ASCII 相容編碼字首),用於向 DNS 及相關軟體表明該標籤是經 Punycode 編碼的國際化域名。瀏覽器等軟體識別到該字首後,通常會將其解碼為原始的 Unicode 字串顯示給使用者。

是的,這是一種被稱為"IDN 同形字攻擊"的釣魚手段。已有報告指出,攻擊者利用外觀幾乎相同但實際不同的字元(例如西里爾字母的"а"與拉丁字母的"a")編碼生成 Punycode 域名(例如 xn--80ak6aa92e.com),冒充正規域名。主流瀏覽器的應對措施包括:當檢測到可疑的字元混用時,在位址列中保持顯示 Punycode 形式(以 xn-- 開頭的字串),而不顯示解碼後的內容。
工具君

閒話 ― "貓"與"日本語"如何變成域名的幕後故事

國際化域名(IDN)的討論始於上世紀 90 年代後期,但標準化經歷了很長時間。為了在不改變 DNS 核心結構的前提下處理非 ASCII 字元,業界曾提出多種方案,最終採用了"在應用層(客戶端)完成編碼與解碼,DNS 伺服器本身保持不變"的 Punycode 方案,並於 2003 年正式標準化為 RFC 3492。

Punycode 由 2003 年 3 月發布的 RFC 3492 規定。作者是加州大學柏克萊分校的 Adam M. Costello,他在同一份 RFC 中定義了名為 Bootstring 的通用演算法(僅用有限的字元表示任意字串),並把為域名決定了參數的實例命名為 Punycode。從 RFC 3492 中的轉換範例都不帶 xn-- 也可以看出,xn-- 不是 Punycode 本身的一部分,而是由 IDNA 加上的字首。另外,RFC 中並沒有說明 Punycode 這個名字的由來。

如今,日語域名(.jp)以及表情符號域名(例如確實存在的 💩.la)等使用各種語言和符號的域名已被實際註冊和使用,但在這些域名背後,始終都要經過 Punycode 的轉換處理。即便是瀏覽器位址列中顯示的優美的日語域名,在與 DNS 伺服器通訊時,實際傳輸的也是以 xn-- 開頭的樸素 ASCII 字串。