在發現我國 CNNIC ROOT 根證書已經悄無聲息混進微軟 Windows 操作系統受信任的根證書頒發機構和 Firefox 火狐瀏覽器受信任證書列表中的事實之后(敏感話題,不再過多談及,只是希望某機構不要做出 MITM 的劣行),我逛了逛 CNNIC 的網站,發現他們在忙著推廣"英文/數字.中國"域名的推廣。這令我又想起了中文域名這個話題,以及當年 3721 和 CNNIC 的一些變故。當然,那些年的那些破事兒不值得一提,值得一提的一個話題是瀏覽器對國際域名(IDN)的支持,和其中涉及到的技術。 在看了一些".中國"域名的例子后,發現新華網(http://www.xinhuanet.com)已經注冊并使用了中文域名"新華網.中國"。于是我使用 IE10 瀏覽器訪問了 http://新華網.中國 。 通過上面的簡述解釋,不難會意出,國際域名指的是瀏覽器地址欄中以非 ASCII 字符集或字母顯示的 Web 地址。這允許各個國家的網站使用本地語言和字符集顯示其地址。其實微軟從 IE7 開始,就已經能夠由瀏覽器處理國際域名了。所謂"處理",就是指瀏覽器將用戶輸入的非英文的域名轉換為編碼后的英文格式。好,這里就涉及到一個問題,為什么要編碼轉換? 我們知道,域名是訪問網站的捷徑,因為網站的 IP 地址太難于記憶,而簡短且富有語義的域名字符,更加便于記憶和使用。可是要訪問到具體的網站,還是得知道該網站的 IP 地址,那么就需要一個中間機構,能將域名轉換為對應的 IP 地址。這個中間結構就是 DNS 域名服務器,而轉換的過程我們稱之為"解析"。域名服務器上記錄了注冊的域名和網站 IP 地址的對應關系,所以,訪問網站時,鍵入的是域名,可域名服務器已經通過查詢自己記錄的域名-IP映射關系,對用戶透明地將域名轉化為了 IP 地址,于是用戶最終訪問到了這個網站。(實際的中間過程會比這里簡述的復雜,可以解釋得更為詳細) DNS最早于1983年由 Paul Mockapetris 發明,原始的技術規范在 RFC 882 中發布。1987年發布的第1034和1035號草案修正了DNS技術規范,并廢除了之前的第882和883號草案。在此之后對因特網標準草案的修改基本上沒有涉及到DNS技術規范部分的改動。互聯網域名一開始就是以英文 ACSII 字符(的子集)命名和提供注冊的,2008年,ICANN(一個國際互聯網組織,負責 IP 地址空間分配、協議標識符指派、通用頂級域名及國家和地區頂級域名系統管理、根服務器系統管理)通過一項決議,允許使用其它語言作為互聯網頂級域名的字符。但是通用標準的 DNS 域名解析系統從設計到今天,都不能解析非英文 ASCII 字符,這就是為什么要在國際域名開放注冊和投入使用后,要將國際域名編碼轉換為 ASCII 字符的原因。簡言之,就是為了與 DNS 系統兼容。(其實還有一個重要原因,是為了防范IDN homograph attack, 即國際域名同形異義字欺騙攻擊,又稱 IDN 欺騙,本文不贅述。) 既然國際域名已經開始使用,瀏覽器提供這種編碼轉換功能,將國際域名中各個國家不同文字形成的域名轉換成特定的用一些 ASCII 英文字符表示的域名,是理所應當的,這樣,用戶便不再需要安裝一些加載項和工具欄來進行轉換,就能直接訪問國際域名。世界上有這么多的國家和語言文字系統,將他們各自語言文字的域名轉換為英文后,還得確保都是唯一的,就得運用同一種編碼規則,而且這種編碼既然是用于互聯網的域名解析系統的,就得使轉換后的編碼不至于太長,且能夠抵御 IDN 欺騙。現在,這種統一的編碼已經存在,它就是 Punycode. Punycode 是一個根據 RFC 3492 制定的編碼系統,主要用于把域名從地方語言所采用的 Unicode 編碼轉換成為可用于 DNS 系統的編碼。該編碼根據由 IANA 提供的域名相異字表制定,它可以在 Unicode 序列和 ASCII 字符串之間進行唯一和可逆的轉換,轉換過程中,Unicode 序列中的 ASCII 字符保持不變,國際化字符則用字母和數字表示。它可以防止 IDN 欺騙。 簡單地看看 Punycode 的一個例子,新華網.cn 的 Punycode 就是 xn--xkrr14bows.cn, "新華網"三個字從中文轉化為 xn--xkrr14bows,而分隔符"."不變,英文字母"cn"也不變。如果后綴不是".cn", 而是".中國",那么分隔符"."仍不變,"中國"編碼為 xn--fiqs8s。既然 DNS 處理的仍舊是不包含國際字符的 Punycode,國際字符是通過瀏覽器轉換成 Punycode 的,那我們訪問 http://xn--xkrr14bows.xn--fiqs8s 等同于訪問 http://新華網.中國。注意,國際字符命名的域名和轉換后的 Punycode 這兩者是一回事兒,是同一個域名,而新華網的英文域名 http://www.xinhuanet.com 是另一個注冊的域名,只不過這兩個域名都指向新華網網站服務器。根據 Punycode 編碼規則,英文和數字不變,因此新華網的英文網址經過 Punycode 編碼后,仍是它本身。 可能有聰明的朋友會問到,為什么不升級 DNS 服務器的 DNS 程序,讓它能直接處理不同語言文字的國際域名呢?其實這不是一個技術問題,而是現實生活中,有太多的域名服務器,他們都同時在支持國際互聯網這個超級大的生產環境,如果要升級,就得同時升級所有的 DNS 服務器,才能確保直接解析國際域名的功能可用,如果升級了一部分,就會導致新的服務問題。就像是 Windows 操作系統的新版本始終得保留一些對舊有系統中程序的兼容性。要徹底淘汰一個東西,可能需要通過很多版本對某一功能進行演化之后,讓這個功能與多年前大不同,并且幾乎沒有人再用多年前的那套東西后,才能淘汰。這樣的例子還有很多,例如雖然現有的 IPv4 地址都已經分配完了,沒有新地址空間了,但是大家都遷移到 IPv6 還需要很長的時間,沒有人能確切地說,什么時候才能徹底淘汰 IPv4 的應用。因此,發明 Punycode 并且讓瀏覽器來講國際域名轉換為 Punycode 是成本低且高度兼容的做法,因此被實施。 好了,說到這里,您應該知道了,國際域名其實還是轉換為了 ASCII 字符中的一些英文字母、數字和部分符號。國際域名的使用同樣需要向域名注冊機構申請注冊,其實域名注冊機構那里和 DNS 系統中保存的不是國際字符,而是 Punycode。現代瀏覽器大多都支持將國際字符按照規則轉化為 Punycode 后再發送給 DNS 服務器查詢。而域名中的"."點分隔符只是起到分隔符的作用,如果您鍵入的是中文分隔符句號"。",一樣不影響。如果您可以正常訪問 http://新華網.中國,或者http://新華網。中國,說明您的瀏覽器至少是支持將中文轉化為 Punycode 的,不妨試試~(網絡) |