对等方组 - 身份






4.80/5 (3投票s)
2006年2月8日
8分钟阅读

30282

288
了解对等方组身份和 Microsoft 的 P2P(点对点)技术。
背景
Microsoft 的 P2P(点对点)分组技术为 Windows P2P(点对点)应用程序提供了稳定、可靠且强大的通信基础设施。对等方使用 Peer Name Resolution Protocol (PNRP - 一种无服务器 DNS) 在组内注册和发现其他对等方。组提供了一种安全的机制,用于在对等方网络中连接对等方、服务和资源。分组允许数据高效、可靠且安全地在对等方之间传输。
Microsoft 的整个点对点技术通过最新的平台 SDK 以 C/C++ API 调用形式公开。但是,本文中的代码展示了如何使用 C# 从 .NET 托管代码调用这些 API。
引言
本文介绍了新的 P2P(点对点)分组概念。与图不同,组提供了一个灵活的安全模型,其中对等方拥有安全身份,并且必须被邀请加入组。对等方必须使用其安全身份加入现有组,然后才能发布记录并与其他对等方进行交互。以下各节总结了理解分组 API 所需的一些核心概念。本文的其余部分将详细介绍身份,包括一个演示如何使用它们的示例应用程序。
概念
身份
在对等方可以创建或加入组之前,它必须拥有一个身份。此身份在组内唯一标识对等方。对等方身份是一个 XML 块,其中包含一个 base-64 编码的证书,该证书包含分配给它的 RSA 公钥。此身份可以导出到文件、复制到另一台计算机并导入。下面显示了一个导出到 XML 的身份
<PEERIDENTITYEXPORT VERSION="1.0">
<PEERNAME>7459f0128f3b452e621df6fd3ed5fe3b7581c148.User1</PEERNAME>
<DATA xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="bin.base64">
TQBJAEkASABDAEEASQBCAEEAegBDAEMAQgBzAFEARwBDAFMAcQBHAFMASQBiADMARABRAEUA
SABBAGEAQwBDAEIAcgBVAEUAZwBnAGEAeABNAEkASQBHAHIAVABDAEMAQQA3ADQARwBDAFMA
cQBHAFMASQBiADMARABRAEUASAANAAoAQQBhAEMAQwBBADYAOABFAGcAZwBPAHIATQBJAEkA
...
agBqAEsAawAwAEMASABrAHgASQBEAHkAcAAzAEsAZQBPAEEAZwBJAEgAMABBAD0APQANAAoA
</DATA>
</PEERIDENTITYEXPORT>
每个身份都有一组凭据,用于在连接到 P2P(点对点)组时验证成员资格。这些凭据表示为 X.509 证书链,称为组成员资格证书。
对等方组
拥有身份后,就可以创建 P2P(点对点)组。组的创建者成为该组的所有者和初始管理员。然后,该管理员可以邀请其他对等方作为受限成员或共享管理员角色。
邀请
只有组的管理员才能创建或刷新邀请。创建邀请需要创建者的身份、要授予被邀请身份的角色(管理员或成员)以及成员资格到期的日期。创建邀请会生成一个 XML 块,可以将其导出到文件,然后发送给对等方(通过复制文件或通过电子邮件发送),最后由对等方导入。可以通过重新发布邀请来刷新现有成员资格,并将其过期日期设置为更远的将来。在这种情况下,可以向必须重新加入组的对等方发送邀请,或者将邀请发布到组,并在对等方下次同步时自动获取。
Joining (汇合)
加入组需要组管理员提供的邀请。如果邀请包含过期日期,您的成员资格最终将过期并被删除(除非管理员刷新了邀请)。但是,也可以创建不包含过期日期的邀请。
会员资格
具有管理员角色的成员可以发布邀请、刷新凭据以及管理发布到组的记录。普通成员只能添加或修改发布到组的记录。无法创建自定义角色。
发布到组的记录使用与对等方图相同的属性架构和搜索机制。组包含创建对等方之间直接连接以及发送和接收私有数据消息的相同功能。分组 API 包括指示实时更改的事件。最后,组的数据库可以与图以相同的方式导出和导入。
感兴趣
任何曾经使用过 Groove 的人都会立即意识到 P2P(点对点)组与 Groove 的工作区之间的相似之处。安装 Groove 后,您首先创建一个唯一标识您的身份。之后,您可以从预配置的模板(如文件、讨论、会议等)创建组(工作区)。您可以将 Groove 安装在最多五个您拥有的计算机上,并在所有计算机之间同步这些工作区。您还可以邀请其他身份(联系人)共享某个工作区。每个工作区都有不同的角色,决定了身份的功能(经理、参与者、访客)。工作区还具有权限,用于确定每个角色在工作区中的操作(创建、编辑、删除等)。
PeerIdentity 类
PeerIdentity
类封装了底层 Identity API 的所有功能。PeerIdentity
对象的每个实例都代表单个身份的属性和行为。在内部,会维护一个 PEER_NAME_PAIR
数据结构的封送处理形式。此数据结构的两个字段公开为属性。
Identity
属性是只读的,并公开与身份关联的名称。
public string Identity
{
get
{
return data.pwzPeerName;
}
}
FriendlyName
属性公开身份的友好名称。设置新的友好名称将调用底层 PeerIdentitySetFriendlyName
API 方法。
public string FriendlyName
{
get
{
return data.pwzFriendlyName;
}
set
{
uint hr = PeerIdentityNative.PeerIdentitySetFriendlyName(Identity, value);
if (hr != 0) throw new PeerIdentityException(hr);
data.pwzFriendlyName = value;
}
}
PeerIdentity
类还提供了一个只读的 Xml
属性,该属性返回用于导入或导出身份的身份的 XML 表示形式。底层 PeerIdentityGetXML
API 方法用于将 XML 片段作为字符串获取。
public string Xml
{
get
{
string xml;
uint hr = PeerIdentityNative.PeerIdentityGetXML(Identity, out xml);
if (hr != 0) throw new PeerIdentityException(hr);
return xml;
}
}
创建身份
PeerIdentity
Create
方法是 static
(Shared
),接受两个参数:name 和 friendly name。一个或两个参数都可以为空。此方法使用底层 PeerIdentityCreate
API 来创建并返回身份。
public static string Create(string Name, string FriendlyName)
{
IntPtr nameptr = IntPtr.Zero;
if (Name != string.Empty)
nameptr = Marshal.StringToHGlobalUni(Name);
IntPtr friendptr = IntPtr.Zero;
if (FriendlyName != string.Empty)
friendptr = Marshal.StringToHGlobalUni(FriendlyName);
string identity;
uint hr = PeerIdentityNative.PeerIdentityCreate(
nameptr, friendptr, IntPtr.Zero, out identity);
if (hr != 0) throw new PeerIdentityException(hr);
return identity;
}
下表显示了传递各种参数值的结果以及生成的身份。
Name 参数 | FriendlyName 参数 | 生成的身份 |
e9ac83642fc11fb162936e51a5586f1ce 4d6e426 | ||
James Bond | 90cb9594c3512104971e91111efd1387 c168be37. James Bond | |
james.bond@mi5.gov.uk | 1d962f531c13b5a8031bb8ea905782dac fb9d74b |
导出身份
PeerIdentity Export
方法使用密码加密身份并返回一个 XML 片段。此方法封装了底层 PeerIdentityExport
API 方法。
public string Export(string Password)
{
string xml;
uint hr = PeerIdentityNative.PeerIdentityExport(
Identity, Password, out xml);
if (hr != 0)
throw new PeerIdentityException(hr);
return xml;
}
导入身份
PeerIdentity
Import
方法尝试使用给定的密码解密 XML 片段。如果 XML 片段不是由 Export
方法生成的,密码不正确,或者身份已存在,则会抛出异常。此方法封装了非托管的 PeerIdentityImport
API 方法。
public static string Import(string Xml, string Password)
{
string identity;
uint hr = PeerIdentityNative.PeerIdentityImport(Xml,
Password, out identity);
if (hr != 0)
{
//if (hr == 0x800700b7) hr = PEER_E_ALREADY_EXISTS);
//if (hr == 0x80070057) hr = ?;
// Either the password or the XML
// formatted peer identity is invalid.
throw new PeerIdentityException(hr);
}
return identity;
}
身份的组别
PeerIdentity
Groups
属性允许您获取身份所属的组的列表。此属性返回一个 PeerGroupCollection
类,该类实现了标准的 IEnumerable
接口。PeerGroupCollection
使用非托管的 PeerEnumGroups
API 来返回和枚举身份所属的组。
列出现有身份
要获取为当前 Windows 用户帐户创建的当前身份列表,请在 foreach
循环中使用 PeerIdentityCollection
类。此类支持标准的 IEnumerable
接口。PeerIdentityCollection
使用非托管的 PeerEnumIdentities
API 来返回和枚举现有身份。
使用示例应用程序
示例应用程序允许您管理您的身份。PeerIdentity
的功能分为不同的选项卡;列出现有身份、创建、导出、导入以及列出身份所属的组。
“身份”选项卡显示了为当前 Windows 用户帐户创建的现有身份列表(参见上图)。相应 PeerIdentity
对象的属性显示在属性网格中。您可以输入新名称并按 Enter 键来修改友好名称。删除按钮允许您删除选定的身份。
“创建”选项卡允许您输入身份名称和友好名称(通常是电子邮件地址)。按“创建”按钮可以看到返回的安全对等方名称。下图显示了一个示例
“导出”选项卡允许您查看 Export 方法生成的 XML 片段并将此身份保存到文件。首先,在“身份”选项卡上选择一个身份。接下来,您必须输入一个密码来加密身份。单击“导出”按钮生成 XML 片段。单击“另存为”按钮将 XML 片段保存到文件。下图显示了一个示例
“导入”选项卡允许您导入以前导出的身份。输入用于加密正在导入文件中的身份的密码。接下来,单击“导入”按钮选择一个文件并导入它。如果发生错误,将显示一个消息框,否则将显示该身份的安全对等方名称。演示包括作者导出的示例身份,您可以导入(密码是“test”)。下图显示了一个示例
“组”选项卡显示了选定身份所属的组。此选项卡上的控件将为空,直到下一篇文章介绍如何创建和加入组。
看点
P2P(点对点)身份 API 还支持使用自定义加密服务提供商来加密身份。但是,由于其复杂性,此功能尚未在托管代码中公开。
此外,Windows Vista 还包含一种额外的方法来返回当前 Windows 用户帐户的默认身份。虽然代码已包含在内,但尚未经过测试,并且肯定会在 Windows XP SP2 上引发异常。
资源链接
我发现以下资源对于理解对等图形非常有帮助
结论
我希望您觉得本文有用。我将撰写更多关于以下主题的文章,以进一步加深您对 Microsoft P2P(点对点)技术的理解
- 对等方组 - 创建、打开和删除
- 对等方组 - 邀请和加入
- 对等协作 - 附近的人
- 对等协作 - 端点
- 对等协作 - 能力
- 对等协作 - 在线状态
- 对等协作 - 邀请
- 对等名称解析 - Windows Vista 增强功能
如果您对其他主题有建议,请留言。
历史
- 初始版本。