处理国际化域名 (IDN)

本主题介绍如何在应用程序中使用国际化域名 (IDN)。 IDN 由网络工作组 RFC 3490:在应用程序中国际化域名 (IDNA) 指定。 在此草案标准发布之前,IDN 仅限于没有音调符号的拉丁字符。 IDNA 允许 IDN 包含带音调符号的拉丁字符,以及非拉丁语脚本(如西里尔文、阿拉伯语和中文)中的字符。 该标准还确立了将 IDN 映射到仅 ASCII 域名的规则。 因此,IDNA 问题可以在客户端处理,而无需更改任何域名服务器 (DNS)。

注意

RFC 3490 引入了许多与使用 IDN 相关的安全问题。 有关详细信息,请参阅安全注意事项的相关部分:国际功能

 

注意

IDNA 目前基于 Unicode 3.2。

 

用于处理 IDN 的 NLS API 函数

NLS 包括以下转换函数,应用程序可以使用这些函数将 IDN 转换为不同的表示形式。 有关使用这些函数的示例,请参阅 NLS:国际化域名 (IDN) 转换示例

  • IdnToAscii。 将 IDN 转换为 Punycode。
  • IdnToNameprepUnicode。 执行 IDN 转换为 ASCII 名称的 NamePrep 部分。 此函数创建字符串的规范 Unicode 表示形式。
  • IdnToUnicode。 将 Punycode 字符串转换为常规 UTF-16 字符串。

NLS 还定义了多个 API 函数,可用于缓解 IDN 技术带来的一些安全风险。 在 Windows Vista 及更高版本中,以下函数用于验证给定 IDN 中的字符是否完全来自与特定区域设置关联的脚本。 有关使用这些函数的示例,请参阅 NLS:国际化域名 (IDN) 风险缓解示例

对于在 Windows XP 和 Windows Server 2003 上运行的应用程序,函数 DownlevelGetLocaleScriptsDownlevelGetStringScriptsDownlevelVerifyScripts 在缓解安全风险方面扮演与上列函数类似的角色。 可从 archive.org 下载的“Microsoft 国际化域名 (IDN) 缓解 API”

处理 Unicode 字符串

IDNA 支持将 Unicode 字符串转换为合法的主机名标签,但包含某些禁止字符的字符串除外,例如控制字符、专用使用区域 (PUA) 中的字符等。 如果函数遇到字母、数字或连字符 (-) 字符以外的 ASCII 字符,或者字符串以连字符减字符开头或结尾,应用程序可以使用具有多个 NLS 转换函数的 IDN_USE_STD3_ASCII_RULES 标志来强制函数失败。 这些字符一直被禁止在域名中使用,草案标准中仍然禁止。

处理未分配的码位

IDN 不能包含未分配的码位。 因此,从 Unicode 3.2 开始,与字符(“已分配”)不关联的码位没有定义 IDN 映射,即使某些转换函数中的 IDN_ALLOW_UNASSIGNED 标志允许它们映射到 Punycode。 可以在 RFC 3454 中找到未分配码位的列表。

注意

如果应用程序将未分配的码位编码为 Punycode,则生成的域名应为非法域名。 如果更高版本的 IDNA 使这些名称合法,或者应用程序筛选出非法字符以尝试创建合法域名,则安全性可能会受到损害。

 

在协议标识符和命名实体(如数字证书的名称和 DNS 域名部分)中使用的存储字符串中不允许使用未分配的码位。 但是,查询字符串中允许码位,例如,数字证书颁发机构和 DNS 查找的用户输入名称,这些名称用于匹配存储的标识符。

注意

尽管查询字符串可以使用未分配的码位,但不应在应用程序中使用它们。 即使是用户提供的查询字符串也存在“欺骗”攻击的风险。 在此类攻击中,无良主机站点会从其打算访问可能向第三方提供敏感信息的另一个网站重新路由用户。 例如,从传入电子邮件复制字符串可能会引发与在浏览器中单击链接相同的风险。

 

将域名转换为 ASCII 名称

应用程序可以使用 IdnToAscii 函数和某些缓解函数将 IDN 转换为 ASCII。

注意

因为二进制表示形式完全不同的字符串可以比较为相同,所以此函数可能会引发某些安全问题。 有关详细信息,请参阅安全注意事项:国际功能中比较函数的讨论。

 

示例

NLS:国际化域名 (IDN) 转换示例演示如何使用 IDN 转换函数。 NLS:国际化域名 (IDN) 风险缓解示例演示如何使用 IDN 缓解函数。

使用区域语言支持

安全注意事项:国际功能