⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 authenticationtoken.cs

📁 Microsoft Mobile Development Handbook的代码,有C#,VB,C++的
💻 CS
字号:
//===============================================================================
// Microsoft patterns & practices
// Mobile Client Software Factory - July 2006
//===============================================================================
// Copyright  Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//===============================================================================
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================

using System;
using System.Collections.Generic;
using System.Text;

namespace Microsoft.Practices.Mobile.PasswordAuthentication
{
	/// <summary>
	///		This class allows you to check a username/password using a saved hash value instead of
	///		saving the username/password.
	/// </summary>
	public class AuthenticationToken
	{
		private const int saltLength = 8;
		private readonly byte[] version = new byte[] { 1, 0 };
		private byte[] tokenData;

		/// <summary>
		///		Creates a new token from an existing identity. Use this constructor to obtain a token that you
		///		can save for later authentication.
		/// </summary>
		/// <param name="identity"></param>
		public AuthenticationToken(PasswordIdentity identity)
		{
			Guard.ArgumentNotNull(identity, "identity");

			//S = create a random salt 
			//U = get user from identitty
			//K = get key from id
			//H = HMACSHA(U, K, S)
			//token data = S + H

			byte[] salt = CryptographyUtility.GetRandomBytes(saltLength);
			tokenData = CalculateToken(identity, salt, identity.Provider);
		}

		/// <summary>
		///		Creates a new instance from a saved token. Use this constructor when you need to authenticate
		///		an existing user against a saved token.
		/// </summary>
		/// <param name="token"></param>
		public AuthenticationToken(string token)
		{
			Guard.ArgumentNotNullOrEmptyString(token, "token");

			this.tokenData = Convert.FromBase64String(token);

			for (int i = 0; i < version.Length; i++)
			{
				if (tokenData[i] != version[i])
					throw new ArgumentException(Properties.Resources.InvalidVersion);
			}
		}

		/// <summary>
		///		Checks to see if the user name and password provided result in the same hash as this
		///		token.
		/// </summary>
		/// <param name="user">Name used to authenticate.</param>
		/// <param name="password">The password used to authenticate.</param>
		/// <param name="provider"></param>
		/// <returns></returns>
		public PasswordIdentity Authenticate(string user, string password, RsaAesCryptographyProvider provider)
		{
			Guard.ArgumentNotNullOrEmptyString(user, "user");
			Guard.ArgumentNotNullOrEmptyString(password, "password");
			Guard.ArgumentNotNull(provider, "provider");

			//
			// Breaks apart the token data so we can use the salt again.
			//
			SubArray<byte> version = new SubArray<byte>(tokenData, 0, 2);
			SubArray<byte> salt = new SubArray<byte>(tokenData, version.Count, saltLength);

			PasswordIdentity identity = new PasswordIdentity(user, password, true, provider);
			byte[] newToken = CalculateToken(identity, salt.Array, provider);

			if (CryptographyUtility.CompareBytes(newToken, tokenData))
				return identity;
			else
				return null;
		}

		/// <summary>
		///		The "token" created from the identity. You can save this value for later use in
		///		authenticating a user, in conjunction with decrypting data.
		/// </summary>
		public string TokenData
		{
			get { return Convert.ToBase64String(tokenData); }
		}

		/// <summary>
		///		Creates a token from a user name, password-derived key, and salt.
		/// </summary>
		/// <param name="identity">The identity that provides the password-derived key and user name.</param>
		/// <param name="salt">Some random data.</param>
		/// <param name="provider">The cryptographic provider used for cyptographic functions.</param>
		/// <returns>Returns a byte array that is a concatination of the version (2 bytes), the salt, and the hash.</returns>
		private byte[] CalculateToken(PasswordIdentity identity, byte[] salt, RsaAesCryptographyProvider provider)
		{
			Guard.ArgumentNotNull(identity, "identity");
			Guard.ArgumentNotNull(salt, "salt");
			Guard.ArgumentNotNull(provider, "provider");

			CryptNativeHelper crypto = new CryptNativeHelper(provider);

			byte[] user = CryptographyUtility.GetBytes(identity.Name);
			byte[] hash = crypto.GetHmacHash(user, salt, identity.CryptoKey);
			byte[] header = CryptographyUtility.CombineBytes(version, salt);
			byte[] token = CryptographyUtility.CombineBytes(header, hash);
			return token;
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -