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

📄 passwordderivebytes.cs

📁 本源码为OpenNETCF源代码
💻 CS
字号:
//==========================================================================================
//
//		OpenNETCF.Windows.Forms.PasswordDeriveBytes
//		Copyright (c) 2003, OpenNETCF.org
//
//		This library is free software; you can redistribute it and/or modify it under 
//		the terms of the OpenNETCF.org Shared Source License.
//
//		This library is distributed in the hope that it will be useful, but 
//		WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 
//		FITNESS FOR A PARTICULAR PURPOSE. See the OpenNETCF.org Shared Source License 
//		for more details.
//
//		You should have received a copy of the OpenNETCF.org Shared Source License 
//		along with this library; if not, email licensing@opennetcf.org to request a copy.
//
//		If you wish to contact the OpenNETCF Advisory Board to discuss licensing, please 
//		email licensing@opennetcf.org.
//
//		For general enquiries, email enquiries@opennetcf.org or visit our website at:
//		http://www.opennetcf.org
//
//		!!! A HUGE thank-you goes out to Casey Chesnut for supplying this class library !!!
//      !!! You can contact Casey at http://www.brains-n-brawn.com                      !!!
//
//==========================================================================================
using System;
using OpenNETCF.Security.Cryptography.NativeMethods;

namespace OpenNETCF.Security.Cryptography
{
	public class PasswordDeriveBytes : DeriveBytes
	{
		private string password;
		private byte [] salt;
		private string hashName;
		int iterations;

		public PasswordDeriveBytes(string password, byte [] salt)
		{
			this.password = password;
			this.salt = salt;
			this.hashName = "SHA1"; //default hash
			this.iterations = 100; //default iterations
		}

		public PasswordDeriveBytes(string password, byte[] salt, string hashName, int iterations)
		{
			this.password = password;
			this.salt = salt;
			this.hashName = hashName;
			this.iterations = iterations;
		}

		//Properties
		public string HashName
		{
			get{return hashName;}
			set{hashName = value;}
		}
		public int IterationCount
		{
			get{return iterations;}
			set{iterations = value;}
		}
		public byte [] Salt
		{
			get{return salt;}
			set{salt = value;}
		}

		/// <summary>
		/// Derives a cryptographic key from the PasswordDeriveBytes object.
		/// </summary>
		/// <remarks>
		/// If the keySize parameter is set to 0, the default key size for the specified algorithm is used.
		/// </remarks>
		/// <param name="algName">The algorithm name for which to derive the key. </param>
		/// <param name="algHashName">The hash algorithm name to use to derive the key. </param>
		/// <param name="keySize">The size of the key to derive. </param>
		/// <param name="IV">The initialization vector (IV) to use to derive the key.</param>
		/// <returns>The derived key.</returns>
		public byte [] CryptDeriveKey(string algName, string algHashName, int keySize, byte [] IV)
		{
			//RC2 / SHA1 works
			//TODO DES / MD5 seems to be salted
			//TODO not using salt, IV, or keySize
			IntPtr prov = Context.AcquireContext();
			
			byte [] baPassword = Format.GetBytes(this.password);
			IntPtr hash = GetHashAlgorithm(prov, algHashName);
			Hash.HashData(hash, baPassword);

			IntPtr key = GetKeyAlgorithm(prov, hash, algName);
			int keyLen = Key.GetKeyLength(key) / 8;
			byte [] baKey = Key.ExportSessionKey(prov, key, keyLen, true);

			Hash.DestroyHash(hash);
			Key.DestroyKey(key);

			Context.ReleaseContext(prov);
			return baKey;
		}

		/// <summary>
		/// Returns pseudo-random key bytes.
		/// </summary>
		/// <param name="cb">The number of pseudo-random key bytes to generate.</param>
		/// <returns>A byte array filled with pseudo-random key bytes.</returns>
		public override byte[] GetBytes(int cb)
		{
			byte[] data = ASCIIEncoder(password);
			if(salt != null)
			{
				byte[] temp = new byte[data.Length + salt.Length];
				Array.Copy(data, 0, temp, 0, data.Length);
				Array.Copy(salt, 0, temp, data.Length, salt.Length);
				data = temp;
			}

			HashAlgorithm ha = GetHashAlgorithm(this.hashName);
			//if(ha is HMACSHA1)
			//	ha = new HMACSHA1(data);
			//if(ha is MACTripleDES)
			//	ha = new MACTripleDES(data);

			if(iterations <= 0) iterations = 1;
			for(int i = 0; i < iterations; i++)
			{
				data = ha.ComputeHash(data);
			}

			byte[] key = new byte[cb];
			Array.Copy(data, 0, key, 0, cb);
			return key;
		}

		/// <summary>
		/// Resets the state of the operation.
		/// </summary>
		public override void Reset()
		{
			this.salt = null;
		}

		private IntPtr GetKeyAlgorithm(IntPtr prov, IntPtr hash, string halg)
		{
			if(halg.ToLower().IndexOf("rc2") != -1)
				return Key.DeriveKey(prov, Calg.RC2, hash, GenKeyParam.EXPORTABLE | GenKeyParam.NO_SALT);
			else if(halg.ToLower().IndexOf("tripledes") != -1)
				return Key.DeriveKey(prov, Calg.TRIP_DES, hash, GenKeyParam.EXPORTABLE | GenKeyParam.NO_SALT);
			else if(halg.ToLower().IndexOf("des") != -1)
				return Key.DeriveKey(prov, Calg.DES, hash, GenKeyParam.EXPORTABLE | GenKeyParam.NO_SALT);
			else
				throw new Exception("unknown hash algorithm");
		}

		private IntPtr GetHashAlgorithm(IntPtr prov, string halg)
		{
			//keyed hashes
			if(halg.ToLower().IndexOf("hmacsha1") != -1)
				return Hash.CreateHash(prov, CalgHash.HMAC);
			if(halg.ToLower().IndexOf("mactripledes") != -1)
				return Hash.CreateHash(prov, CalgHash.MAC);
			//normal hashes
			if(halg.ToLower().IndexOf("md5") != -1)
				return Hash.CreateHash(prov, CalgHash.MD5);
			else if(halg.ToLower().IndexOf("sha") != -1)
				return Hash.CreateHash(prov, CalgHash.SHA1);
			else
				throw new Exception("unknown hash algorithm");
		}

		private HashAlgorithm GetHashAlgorithm(string halg)
		{
			//keyed hashes
			if(halg.ToLower().IndexOf("hmacsha1") != -1)
				return new HMACSHA1();
			if(halg.ToLower().IndexOf("mactripledes") != -1)
				return new MACTripleDES();
				//normal hashes
			else if(halg.ToLower().IndexOf("md5") != -1)
				return new MD5CryptoServiceProvider();
			//else if(halg.ToLower().IndexOf("sha256") != -1)
			//	return new SHA256Managed();
			else if(halg.ToLower().IndexOf("sha1") != -1) //also in hmacsha1
				return new SHA1CryptoServiceProvider();
			else if(halg.ToLower().IndexOf("sha") != -1) //some form of sha last
				return new SHA1CryptoServiceProvider();
			else
				throw new Exception("unknown hash algorithm");
		}

		private static byte[] ASCIIEncoder(string s)
		{
			byte[] ascii = new byte[s.Length];
			for(int i = 0; i < s.Length; i++)
			{
				ascii[i] = (byte)s[i];
			}
			return ascii;
		}
	}
}

⌨️ 快捷键说明

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