Click here to Skip to main content
13,287,273 members (48,226 online)
Click here to Skip to main content
Add your own
alternative version


16 bookmarked
Posted 8 Feb 2006

Peer Group - Identities

, 8 Feb 2006
Rate this:
Please Sign up or sign in to vote.
Understanding Peer Group Identities and Microsoft's Peer-to-Peer technology.


Microsoft's Peer-to-Peer Grouping technology provides a stable, reliable, and robust infrastructure for Windows peer-to-peer applications to communicate. Peers use Peer Name Resolution Protocol (PNRP - a serverless DNS) to register and discover other peers within a group. Groups provide a secure mechanism for connecting peers, services, and resources within a peer network. Grouping allows data to be passed between peers efficiently, reliably, and securely.

Microsoft's entire Peer-to-Peer technology is exposed through the latest Platform SDK as C/C++ API calls. However, the code in this article shows these APIs being used from .NET managed code using C#.


This article introduces new peer-to-peer group concepts. Unlike graphs, groups provide a flexible security model in which peers have secure identities and must be invited to a group. Peers must join an existing group using their secure identity before they can publish records and interact with other peers. The following sections summarize some of the core concepts needed to understand the grouping APIs. The remainder of the article provides more detail about identities, including a sample application demonstrating how to use them.



Before a peer can create or join a group, it must have an identity. This identity uniquely identifies the peer within a group. A peer identity is an XML blob containing a base-64 encoded certificate that contains the RSA public key assigned to it. This identity can be exported to a file, copied to another computer, and imported. The following shows an identity exported to XML:

  <DATA xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="bin.base64">

Each identity has a set of credentials that is used to verify membership when connecting to a peer-to-peer group. These credentials are represented as chains of X.509 certificates called Group Membership Certificates.

Peer Group

Once you have an identity, you can create a peer-to-peer group. The creator of a group becomes the owner and initial administrator of the group. This administrator can then invite other peers as either limited members or share the role of administrator.


Only an administrator of a group can creator or refresh an invitation. Creating an invitation requires the creator's identity, the role to be given to the identity being created (administrator or member), and a date when the membership expires. Creating an invitation results in an XML blob that can be exported to a file, sent to the peer (by copying the file or sending it by e-mail), and finally imported by the peer. Existing memberships can be refreshed with an expiration date further in the future by reissuing an invitation. In this case, the invitation can either be sent to the peer who must re-join the group, or the invitation can be published to the group and automatically picked up by the peer the next time it synchronizes.


Joining a group requires an invitation provided by an administrator of the group. If the invitation includes an expiration date, eventually your membership will expire and be deleted (unless the invitation is refreshed by an administrator). However, it is possible to create an invitation that does not expire.


Members with the administrator role can issue invitations, refresh credentials, and manage records published to the group. Normal members can only add or modify records published to the group. There is no ability to create custom roles.

The records published to a group use the same attribute schema and searching mechanism used by peer graphs. Groups include the same ability to create direct connections between peers, and send and receive private data messages. The grouping API includes events to indicate live changes. Finally, a group's database can be exported and imported in the same manner as a graph.

Of Interest

Anyone who has ever used Groove will immediately recognize the similarity between peer-to-peer groups and Groove's workspaces. After installing Groove, you first create an identity which uniquely identities you. After this, you can create groups (workspaces) from pre-configured templates such as files, discussions, meetings, etc. You can install Groove on up to five computers that you own, and synchronize these workspaces between all computers. You can also invite other identities (contacts) to share a given workspace. Each workspace has different roles that determines the capabilities of an identity (manager, participant, guest). A workspace also has permissions that determines what each role can do in the workspace (create, edit, delete, etc.).

PeerIdentity Class

The PeerIdentity class wraps all the functionality of the underlying Identity APIs. Each instance of a PeerIdentity object represents the properties and behavior of a single identity. Internally, a marshaled form of the PEER_NAME_PAIR data structure is maintained. Two fields of this data structure are exposed as properties.

The Identity property is read-only and exposes the name associated with the identity.

public string Identity
    return data.pwzPeerName;

The FriendlyName property exposes the friendly name of the identity. Setting a new friendly name results in calling the underlying PeerIdentitySetFriendlyName API method.

public string FriendlyName
    return data.pwzFriendlyName;

    uint hr = PeerIdentityNative.PeerIdentitySetFriendlyName(Identity, value);
    if (hr != 0) throw new PeerIdentityException(hr);
    data.pwzFriendlyName = value;

The PeerIdentity class also provides a read-only Xml property which returns the XML representation of the identity used for importing or exporting the identity. The underlying PeerIdentityGetXML API method is used to get the XML fragment as a string.

public string Xml
    string xml;
    uint hr = PeerIdentityNative.PeerIdentityGetXML(Identity, out xml);
    if (hr != 0) throw new PeerIdentityException(hr);
    return xml;

Creating an Identity

The PeerIdentity Create method is static (Shared) and takes two parameters; name and friendly name. Either or both parameters can be blank. This method uses the underlying PeerIdentityCreate API to create and return the identity.

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;

The following table shows the results of passing various parameter values and the resulting identity.

<!-- fpstyle: 1,011111100 -->
Name ParameterFriendlyName ParameterResulting Identity
  e9ac83642fc11fb162936e51a5586f1ce 4d6e426
James Bond 90cb9594c3512104971e91111efd1387 c168be37. James Bond fb9d74b

Exporting an Identity

The PeerIdentity Export method encrypts the identity with a password and returns an XML fragment. This method wraps the underlying PeerIdentityExport API method.

public string Export(string Password)
  string xml;
  uint hr = PeerIdentityNative.PeerIdentityExport(
                      Identity, Password, out xml);
  if (hr != 0)
      throw new PeerIdentityException(hr);

  return xml;

Importing an Identity

The PeerIdentity Import method attempts to decrypt an XML fragment using the given password. If the XML fragment was not generated by the Export method, the password is incorrect or the identity already exists, and an exception is thrown. This method wraps the unmanaged PeerIdentityImport API method.

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;

Group Membership of an Identity

The PeerIdentity Groups property allows you to get a list of the groups to which the identity is a member. This property returns a PeerGroupCollection class which implements the standard IEnumerable interface. PeerGroupCollection uses the unmanaged PeerEnumGroups API to return and enumerate the groups to which an identity is a member.

Listing Existing Identities

To get a list of the current identities created for the Windows user account, use the PeerIdentityCollection class in a foreach loop. This class supports the standard IEnumerable interface. PeerIdentityCollection uses the unmanaged PeerEnumIdentities API to return and enumerate the existing identities.

Using the Sample Application

The sample application allows you to manage your identities. Features of a PeerIdentity are divided into different tabs; listing existing identities, creating, exporting, importing, and listing the groups of which the identity is a member.

The Identities tab shows a list of existing identities created for the current Windows user account (see image above). The properties of the corresponding PeerIdentity object are displayed in a property grid. You can modify the friendly name by entering a new name and pressing Enter. The delete button allows you to delete the selected identity.

The Create tab lets you enter the name of the identity and a friendly name (usually an e-mail address). Press the Create button to see the secure peer name returned. The following image shows an example:

The Export tab lets you see the XML fragment generated by the Export method and save this identity to a file. First, select an identity on the Identities tab. Next, you must enter a password to encrypt the identity. Click the Export button to generate the XML fragment. Click the Save As button to save the XML fragment to a file. The following image shows an example:

The Import tab lets you import a previous exported identity. Enter the password used to encrypt the identity in the file being imported. Next, click the Import button to select a file and import it. A message box is displayed if an error occurs, otherwise, the secure peer name of the identity is displayed. The demo includes an example identity exported by the author which you can import (the password is 'test'). The following image shows an example:

The Groups tab shows you the groups of which the selected identity is a member. The controls on this tab will be blank until the next article shows how to create and join groups.

Point of Interest

The peer-to-peer identity API also supports the ability to use a custom cryptographic service provider to encrypt identities. However, due to its complexity, this feature has not been exposed in managed code.

Also, Windows Vista includes an additional method to return the default identity of the current Windows user account. While the code for this is included, it has not been tested and will certainly throw an exception on Windows XP SP2.

Links to Resources

I have found the following resources to be very useful in understanding peer graphs:


I hope you have found this article useful. I will be writing more articles on the following subjects to further your understanding of Microsoft's Peer-to-Peer technology:

  1. Peer Groups - Create, Open, and Delete
  2. Peer Groups - Invitations and Joining
  1. Peer Collaboration - People Near Me
  2. Peer Collaboration - EndPoints
  3. Peer Collaboration - Capabilities
  4. Peer Collaboration - Presence
  5. Peer Collaboration - Invitations
  1. Peer Name Resolution - Windows Vista Enhancements

If you have suggestions for other topics, please leave a comment.


  • Initial revision.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Web Developer
Canada Canada
Adrian Moore is the Development Manager for the SCADA Vision system developed by ABB Inc in Calgary, Alberta.

He has been interested in compilers, parsers, real-time database systems and peer-to-peer solutions since the early 90's. In his spare time, he is currently working on a SQL parser for querying .NET DataSets (

Adrian is a Microsoft MVP for Windows Networking.

You may also be interested in...

Comments and Discussions

-- There are no messages in this forum --
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.171207.1 | Last Updated 8 Feb 2006
Article Copyright 2006 by Adrian_Moore
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid