Esempio n. 1
0
		public override byte [] EncryptValue(byte [] key)
		{
			//http://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html
			byte[] bs1 = _tdcsp.Key;
			SHA1CryptoServiceProvider sha1Csp = new SHA1CryptoServiceProvider();
			byte[] bs2 = sha1Csp.ComputeHash(key);
			RNGCryptoServiceProvider rNGCryptoServiceProvider = new RNGCryptoServiceProvider();
			byte[] bs3 = new byte[8];
			rNGCryptoServiceProvider.GetBytes(bs3);
			byte[] bs4 = new byte[(int)key.Length + 8];
			_tdcsp.IV = bs3;
			Buffer.BlockCopy(key, 0, bs4, 0, (int)key.Length);
			Buffer.BlockCopy(bs2, 0, bs4, (int)key.Length, 8);				
			TripleDesNoPadding tdnp1 = new TripleDesNoPadding(_tdcsp);
			byte [] bs5 = tdnp1.Encrypt(bs4);
			byte[] bs6 = new byte[(int)bs3.Length + (int)bs5.Length];
			Buffer.BlockCopy(bs3, 0, bs6, 0, (int)bs3.Length);
			Buffer.BlockCopy(bs5, 0, bs6, (int)bs3.Length, (int)bs5.Length);
			Array.Reverse(bs6, 0, bs6.Length);
			_tdcsp.Key = bs1;
			_tdcsp.IV = kwIv;
			TripleDesNoPadding tdnp2 = new TripleDesNoPadding(_tdcsp);
			byte [] cipher = tdnp2.Encrypt(bs6);
			return cipher;
		}
		public UsernameToken(string username, string password, 
			PasswordOption passType, EncodingType encType)
		{
			this.Username = new Username();
			this.Username.Text = username;

			System.Guid g = GuidEx.NewGuid();
			this.Id = "SecurityToken-" + g.ToString("D");

			if(passType == PasswordOption.SendNone)
			{
				this.Password = null;
				DateTime dtCreated = DateTime.UtcNow;
				this.Created = XmlConvert.ToString(dtCreated, "yyyy-MM-ddTHH:mm:ssZ");

				this.Nonce = new Nonce();
				byte [] baNonce = OpenNETCF.Security.Cryptography.NativeMethods.Rand.GetRandomBytes(20);
				this.Nonce.Text = Convert.ToBase64String(baNonce, 0, baNonce.Length);
				return;
			}

			this.Password = new Password();

			if(passType == PasswordOption.SendPlainText)
			{
				//this.Password.Type = "wsse:PasswordText";
				this.Password.Type = Misc.tokenProfUsername + "#PasswordText";
				this.Password.Text = password;
			}

			if(passType == PasswordOption.SendHashed)
			{
				//this.Password.Type = "wsse:PasswordDigest";
				this.Password.Type = Misc.tokenProfUsername + "#PasswordDigest";

				DateTime dtCreated = DateTime.UtcNow;
				this.Created = XmlConvert.ToString(dtCreated, "yyyy-MM-ddTHH:mm:ssZ");
				byte [] baCreated = Encoding.UTF8.GetBytes(this.Created);

				this.Nonce = new Nonce();
				//this random number gen is not as strong
				//Random r = new Random(Environment.TickCount);
				//byte [] baNonce = new byte[20];
				//r.NextBytes(baNonce);
				byte [] baNonce = OpenNETCF.Security.Cryptography.NativeMethods.Rand.GetRandomBytes(20);
				this.Nonce.Text = Convert.ToBase64String(baNonce, 0, baNonce.Length);

				byte [] baPassword = Encoding.UTF8.GetBytes(password);

				int baDigestLength = baNonce.Length + baCreated.Length + baPassword.Length; 
				byte [] baDigest = new byte[baDigestLength]; 
				Array.Copy(baNonce, 0, baDigest, 0, baNonce.Length); 
				Array.Copy(baCreated, 0, baDigest, baNonce.Length, baCreated.Length); 
				Array.Copy(baPassword, 0, baDigest, baNonce.Length + baCreated.Length, baPassword.Length);
 				
				//byte [] hash = Hash.ComputeHash(CalgHash.SHA1, baDigest);
				SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
				byte [] hash = sha1.ComputeHash(baDigest);

				if(encType == EncodingType.Base64Binary)
				{
					//default is Base64Binary so dont have to set
					//this.Password.Type = "wsse:Base64Binary";
					this.Password.Text = Convert.ToBase64String(hash, 0, hash.Length);
				}
				if(encType == EncodingType.HexBinary)
				{
					//this.Password.Type = "wsse:HexBinary";
					this.Password.Type = Misc.tokenProfUsername + "#HexBinary";
					this.Password.Text = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetHexBin(hash);
				}
			}
		}
		//public static string ClearPassword;

		/*
		-generate (in order)
		1) gen refs in SignedInfo 
		2) construct SignedInfo and create sig element
		1) obtain raw data
		add wsu:Id to everything
		apply transforms / canonical
		calculate digest
		create ref elem
		2) create signed info
		apply canonical
		create actual signature value
		sig element
		w/SignedInfo, SigVlaue, KeyInfo, ...
		*/
		public static XmlDocument SignXml(XmlDocument plainDoc)
		{
			if(SigObj == null)
				return plainDoc; //nothing to sign

			XmlElement envelope = plainDoc.DocumentElement;

			XmlElement headerOrBody = (XmlElement) envelope.ChildNodes[0];
			XmlElement header;
			XmlElement body;
			if(headerOrBody.LocalName == Elem.Body)
			{
				header = plainDoc.CreateElement(headerOrBody.Prefix, Elem.Header, headerOrBody.NamespaceURI);
				envelope.InsertBefore(header, headerOrBody);
			}
			header = (XmlElement) envelope.ChildNodes[0];
			body = (XmlElement) envelope.ChildNodes[1];
			XmlNodeList headers = header.ChildNodes;
			XmlElement security = null;
			foreach(XmlNode xn in headers)
			{
				if(xn.LocalName == Elem.Security)
					security = (XmlElement) xn;
			}
			if(security == null)
			{
				security = plainDoc.CreateElement(Pre.wsse, Elem.Security, Ns.wsseLatest);
				XmlAttribute mustUnderstand = plainDoc.CreateAttribute(Pre.soap, Attrib.mustUnderstand, Ns.soap);
				mustUnderstand.Value = "1";
				security.Attributes.Append(mustUnderstand);
				header.AppendChild(security);
			}

			XmlElement tokenElem = null;
			string secTokId = null;
			string sigAlgVal = null;
			//add BinarySecurityToken or UsernameToken under Security
			if(SigObj.BinSecTok != null)
			{
				XmlElement binSecTok = SigObj.BinSecTok.WriteXml(plainDoc, security);
				
				secTokId = SigObj.BinSecTok.Id;
				sigAlgVal = Alg.rsaSha1;
				if(SigObj.AsymmAlg is DSACryptoServiceProvider)
					sigAlgVal = Alg.dsaSha1;
				tokenElem = binSecTok;
			}
			/*
			<wsse:UsernameToken xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility" wsu:Id="SecurityToken-344570f1-e3b7-42fc-9b78-f0dcd1f90bd8">
				<wsse:Username>Admin</wsse:Username>
				<wsse:Password Type="wsse:PasswordDigest">W5xVfXpb+NoV9KaPIQXUIslGGak=</wsse:Password>
				<wsse:Nonce>+7L+k37JW8qQCK1SPopXeQ==</wsse:Nonce>
				<wsu:Created>2003-10-23T04:40:04Z</wsu:Created>
			</wsse:UsernameToken>
			*/
			if(SigObj.UserTok != null)
			{
				XmlElement userTokElem = SigObj.UserTok.WriteXml(plainDoc, security);
				tokenElem = userTokElem;
				/*
				//xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
				XmlElement userTokElem = plainDoc.CreateElement(Pre.wsse, Elem.UsernameToken, Ns.wsseLatest);
				security.AppendChild(userTokElem);
				XmlAttribute uid = plainDoc.CreateAttribute(Pre.wsu, Attrib.Id, Ns.wsuLatest);
				uid.Value = SigObj.UserTok.Id;
				userTokElem.Attributes.Append(uid);
				XmlElement userElem = plainDoc.CreateElement(Pre.wsse, Elem.Username, Ns.wsseLatest);
				userElem.InnerText = SigObj.UserTok.Username.Text;
				userTokElem.AppendChild(userElem);
				if(SigObj.UserTok.Password != null)
				{
					XmlElement passElem = plainDoc.CreateElement(Pre.wsse, Elem.Password, Ns.wsseLatest);
					XmlAttribute type = plainDoc.CreateAttribute(Attrib.Type);
					type.Value = SigObj.UserTok.Password.Type;
					passElem.Attributes.Append(type);
					passElem.InnerText = SigObj.UserTok.Password.Text;
					userTokElem.AppendChild(passElem);
				}
				XmlElement nonceElem = plainDoc.CreateElement(Pre.wsse, Elem.Nonce, Ns.wsseLatest);
				nonceElem.InnerText = SigObj.UserTok.Nonce.Text;
				userTokElem.AppendChild(nonceElem);
				XmlElement creElem = plainDoc.CreateElement(Pre.wsu, Elem.Created, Ns.wsuLatest);
				creElem.InnerText = SigObj.UserTok.Created;
				userTokElem.AppendChild(creElem);
				userTokElem.Attributes.Append(uid);
				*/
				secTokId = SigObj.UserTok.Id;
				sigAlgVal = Alg.hmacSha1;
			}
			if(SigObj.securityContextToken != null)
			{
				XmlNode sctNode = LameXpath.SelectSingleNode(header, Elem.SecurityContextToken);
				if(sctNode == null)
				{
					//i need to import this node 1st
					sctNode = plainDoc.ImportNode(SigObj.securityContextToken, true);
					string dupeId = sctNode.Attributes[Attrib.Id, Ns.wsuLatest].Value;
					XmlElement dupeElem = LameXpath.SelectSingleNode(dupeId, security);
					if(dupeElem == null)
						security.AppendChild(sctNode);
					else
						sctNode = LameXpath.SelectSingleNode(dupeId, security);
				}
				//<wsse:SecurityContextToken wsu:Id=\"SecurityToken-feb27552-6eb5-4a27-a831-e1bdfca326e2\">
				secTokId = sctNode.Attributes[Attrib.Id, Ns.wsuLatest].Value;
				sigAlgVal = Alg.hmacSha1;
				tokenElem = (XmlElement) sctNode;

				if(SigObj.derKeyTok != null)
				{
					XmlNode idElem = LameXpath.SelectSingleNode(sctNode, Elem.Identifier);
					if(idElem != null)
						SigObj.derKeyTok.secTokRef.Reference.URI = idElem.InnerText;

					XmlElement derKeyTokElem = SigObj.derKeyTok.WriteXml(plainDoc, security, (XmlElement) sctNode);
					secTokId = SigObj.derKeyTok.id;
				}
			}
			

			//add Signature element, SignedInfo, CanonicalizationMethod and SignatureMethod
			XmlElement sigElem = plainDoc.CreateElement(Pre.ds, Elem.Signature, Ns.ds);
			security.AppendChild(sigElem); //just append
			//add SignedInfo
			XmlElement sigInfoElem = plainDoc.CreateElement(Pre.ds, Elem.SignedInfo, Ns.ds);
			sigElem.AppendChild(sigInfoElem);
			XmlElement canMethElem = plainDoc.CreateElement(Pre.ds, Elem.CanonicalizationMethod, Ns.ds);
			XmlAttribute canAlg = plainDoc.CreateAttribute(Attrib.Algorithm);
			canAlg.Value = Alg.xmlExcC14n;
			canMethElem.Attributes.Append(canAlg);
			sigInfoElem.AppendChild(canMethElem);
			XmlElement sigMethElem = plainDoc.CreateElement(Pre.ds, Elem.SignatureMethod, Ns.ds);
			XmlAttribute sigAlg = plainDoc.CreateAttribute(Attrib.Algorithm);
			sigAlg.Value = sigAlgVal;
			sigMethElem.Attributes.Append(sigAlg);
			sigInfoElem.AppendChild(sigMethElem);
			
			//get each Refs element, add Id if missing
			//canonical, Digest, add ReferenceElement
			bool comments = false;
			bool exclusive = true;
			SHA1CryptoServiceProvider shaCsp = new SHA1CryptoServiceProvider();
			foreach(object oRef in SigObj.Refs)
			{
				XmlElement refdElem = LameXpath.SelectSingleNode(plainDoc, oRef.ToString());
                if(refdElem == null)
					continue; //cant sign it because it doesnt exist
				//get or add Id
				XmlAttribute xaId = null;
				foreach(XmlAttribute xa in refdElem.Attributes)
				{
					if(xa.LocalName == Attrib.Id)
					{
						xaId = xa;
						break;
					}
				}
				if(xaId == null)
				{
					xaId = plainDoc.CreateAttribute(Pre.wsu, Attrib.Id, Ns.wsuLatest);
					string preId = "Id-";
					if(oRef.ToString() == Elem.Timestamp)
						preId = "Timestamp-";
					xaId.Value = preId + GuidEx.NewGuid().ToString("D");
					refdElem.Attributes.Append(xaId);
				}
				XmlDocument xdRefd = new XmlDocument();
				xdRefd.LoadXml(refdElem.OuterXml);
				XmlCanonicalizer xc = new XmlCanonicalizer(comments, exclusive);
				MemoryStream msRefd = (MemoryStream) xc.Canonicalize(xdRefd);
				byte [] baRefd = new byte[msRefd.Length];
				msRefd.Read(baRefd, 0, baRefd.Length);
				string debugName = oRef.ToString();
				byte [] baDigest = shaCsp.ComputeHash(baRefd);
                XmlElement refElem = plainDoc.CreateElement(Pre.ds, Elem.Reference, Ns.ds);
				XmlAttribute refUri = plainDoc.CreateAttribute(Attrib.URI);
				refUri.Value = "#" + xaId.Value;
				refElem.Attributes.Append(refUri);
				sigInfoElem.AppendChild(refElem);
				XmlElement transsElem = plainDoc.CreateElement(Pre.ds, Elem.Transforms, Ns.ds);
				refElem.AppendChild(transsElem);
				XmlElement transElem = plainDoc.CreateElement(Pre.ds, Elem.Transform, Ns.ds);
				XmlAttribute transAlg = plainDoc.CreateAttribute(Attrib.Algorithm);
				transAlg.Value = Alg.xmlExcC14n;
				transElem.Attributes.Append(transAlg);
				transsElem.AppendChild(transElem);
                XmlElement digMethElem = plainDoc.CreateElement(Pre.ds, Elem.DigestMethod, Ns.ds);
				XmlAttribute digMethAlg = plainDoc.CreateAttribute("Algorithm");
				digMethAlg.Value = Alg.sha1;
				digMethElem.Attributes.Append(digMethAlg);
				refElem.AppendChild(digMethElem);
				XmlElement digValElem = plainDoc.CreateElement(Pre.ds, Elem.DigestValue, Ns.ds);
				digValElem.InnerText = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(baDigest);
				refElem.AppendChild(digValElem);
			}

			//canonical SignedInfo, get key, get signature
			XmlDocument xdSigInfo = new XmlDocument();
			xdSigInfo.LoadXml(sigInfoElem.OuterXml);
			XmlCanonicalizer xcSi = new XmlCanonicalizer(comments, exclusive);
			MemoryStream msSigInfo = (MemoryStream) xcSi.Canonicalize(xdSigInfo);
			byte [] baSigInfo = new byte[msSigInfo.Length];
			msSigInfo.Read(baSigInfo, 0, baSigInfo.Length);
			byte [] baSig = null;
			if(SigObj.BinSecTok != null)
			{
				byte [] baUnsigHash = shaCsp.ComputeHash(baSigInfo);
				baSig = SigObj.AsymmAlg.SignHash(baUnsigHash, "SHA");
			}
			if(SigObj.UserTok != null)
			{
				byte [] derKey = P_SHA1.DeriveKey(SigObj.ClearPassword, StrKeyLabel, SigObj.UserTok.Nonce.Text, SigObj.UserTok.Created, NumKeyBytes);
				HMACSHA1 hs = new HMACSHA1(derKey);
				baSig = hs.ComputeHash(baSigInfo);
			}
			if(SigObj.securityContextToken != null)
			{
				//XmlElement createdElem = LameXpath.SelectSingleNode(SigObj.securityContextToken, "Created");
				//string strCreated = createdElem.InnerText; //2004-03-05T01:59:49Z
				//string label = "WS-Security";
				////byte [] baKey = P_SHA1.DeriveKey(password, label, nonce, created, 24);
				//byte [] baKey = P_SHA1.DeriveKey(String.Empty, label, String.Empty, strCreated, 24);
				//HMACSHA1 hs = new HMACSHA1(baKey);
				//baSig = hs.ComputeHash(baSigInfo);
				byte [] hashKey;
				if(SigObj.derKeyTok != null)
					hashKey = SigObj.derKeyTok.derKey;
				else
					hashKey = SigObj.securityContextKey;
				HMACSHA1 hs = new HMACSHA1(hashKey);
				baSig = hs.ComputeHash(baSigInfo);
			}

			//add SignatureValue
			XmlElement sigValElem = plainDoc.CreateElement(Pre.ds, Elem.SignatureValue, Ns.ds);
			sigValElem.InnerText = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(baSig);
			sigElem.AppendChild(sigValElem);
			//add KeyInfo
			XmlElement keyInfoElem = plainDoc.CreateElement(Pre.ds, Elem.KeyInfo, Ns.ds);				
			XmlElement secTokRefElem = plainDoc.CreateElement(Pre.wsse, Elem.SecurityTokenReference, Ns.wsseLatest);
			XmlElement sigRefElem = plainDoc.CreateElement(Pre.wsse, Elem.Reference, Ns.wsseLatest);
			XmlAttribute uri = plainDoc.CreateAttribute(Attrib.URI);
			uri.Value = "#" + secTokId;
			sigRefElem.Attributes.Append(uri);
			XmlAttribute valueType = plainDoc.CreateAttribute(Attrib.ValueType);
			valueType.Value = "#" + secTokId;
			sigRefElem.Attributes.Append(valueType);
			
			if(SigObj.UserTok != null)
			{
				XmlAttribute valType = plainDoc.CreateAttribute(Attrib.ValueType);
				valType.Value = Misc.tokenProfUsername + "#UsernameToken";
				sigRefElem.Attributes.Append(valType);
			}
			if(SigObj.BinSecTok != null)
			{
				XmlAttribute valType = plainDoc.CreateAttribute(Attrib.ValueType);
				valType.Value = Misc.tokenProfX509 + "#X509v3";
				sigRefElem.Attributes.Append(valType);
			}
			
			secTokRefElem.AppendChild(sigRefElem);
			keyInfoElem.AppendChild(secTokRefElem);
			sigElem.AppendChild(keyInfoElem);

			//SigObj = null;
			return plainDoc;
		}
		public static void VerifySig(XmlDocument sigDoc)
		{
			try
			{
				XmlElement envelope = sigDoc.DocumentElement;

				XmlElement securityElem = LameXpath.SelectSingleNode(sigDoc, Elem.Security);
				if(securityElem != null)
				{
					XmlAttribute mustUndAtt = securityElem.Attributes[Attrib.mustUnderstand,Ns.soap];
					if(mustUndAtt != null)
						mustUndAtt.Value = "0";
				}

				XmlElement sigElem = LameXpath.SelectSingleNode(sigDoc, Elem.Signature);
				if(sigElem == null)
					return;

				XmlElement sigValElem = LameXpath.SelectSingleNode(sigElem, Elem.SignatureValue);
				byte [] baSigVal = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(sigValElem.InnerText);

				bool comments = false;
				bool exclusive = true;
				SHA1CryptoServiceProvider shaCsp = new SHA1CryptoServiceProvider();

				XmlElement sigMethElem = LameXpath.SelectSingleNode(sigElem, Elem.SignatureMethod);
				string segMeth = sigMethElem.Attributes["Algorithm"].Value;

				XmlElement signedInfoElem = LameXpath.SelectSingleNode(sigElem, Elem.SignedInfo);
				XmlDocument xdSignedInfo = new XmlDocument();
				xdSignedInfo.LoadXml(signedInfoElem.OuterXml);
				XmlCanonicalizer xc = new XmlCanonicalizer(comments, exclusive);
				MemoryStream ms = (MemoryStream) xc.Canonicalize(xdSignedInfo);
				byte [] baMs = new byte[ms.Length];
				ms.Read(baMs, 0, baMs.Length);

				ArrayList keyInfoRefElem = LameXpath.SelectChildNodes(sigElem, Elem.SecurityTokenReference, Elem.Reference);
				XmlElement keyInfoRef = (XmlElement) keyInfoRefElem[0];
				string secTokUri = keyInfoRef.Attributes["URI"].Value;
				secTokUri = secTokUri.TrimStart(new char[]{'#'});
				XmlElement secTokElem = LameXpath.SelectSingleNode(secTokUri, sigDoc);
			
				if(secTokElem.LocalName == Elem.UsernameToken)
				{
					XmlElement nonce = LameXpath.SelectSingleNode(secTokElem, Elem.Nonce);
					XmlElement created = LameXpath.SelectSingleNode(secTokElem, Elem.Created);
					//DerivedKeyGenerator seems to be off by 1?
					//byte [] baKey = P_SHA1.DeriveKey(ClearPassword, StrKeyLabel, nonce.InnerText, created.InnerText, NumKeyBytes);
					byte [] baKey = P_SHA1.DeriveKey(SigObj.ClearPassword, StrKeyLabel, nonce.InnerText, created.InnerText, NumKeyBytes);
					HMACSHA1 hmacSha = new HMACSHA1(baKey);
					byte [] baSig = hmacSha.ComputeHash(baMs);
					OpenNETCF.Security.Cryptography.NativeMethods.Format.SameBytes(baSigVal, baSig);
				}
				else if(secTokElem.LocalName == Elem.BinarySecurityToken)
				{
					byte [] baCert = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(secTokElem.InnerText);
					X509Certificate cert = new X509Certificate(baCert); //pub key to verify sig.
					byte [] exponent;
					byte [] modulus;
					DecodeCertKey.GetPublicRsaParams(cert, out exponent, out modulus);
					RSAParameters rsaParam = new RSAParameters();
					rsaParam.Exponent = exponent;
					rsaParam.Modulus = modulus;
					RSACryptoServiceProvider rsaCsp = new RSACryptoServiceProvider();
					rsaCsp.ImportParameters(rsaParam);
               
					byte [] baUnsigHash = shaCsp.ComputeHash(baMs);
					bool valid = rsaCsp.VerifyHash(baUnsigHash, "SHA", baSigVal);
					if(valid == false)
						throw new Exception("signature is not valid");
				}
				else if(secTokElem.LocalName == Elem.SecurityContextToken)
				{
					//TODO how to validate signature?
				}
				else
				{
					throw new Exception("only support Username, BinarySecurity, and SecurityContext Token signature");
				}

				//verify reference hashes
				string refdName = String.Empty;
				ArrayList refNodes = LameXpath.SelectChildNodes(sigDoc, Elem.SignedInfo, Elem.Reference);
				foreach(object oXn in refNodes)
				{
					XmlNode xn = (XmlNode) oXn;
					string uriId = xn.Attributes[Attrib.URI].Value;
					uriId = uriId.TrimStart(new char[]{'#'});
					XmlElement digValElem = LameXpath.SelectSingleNode(xn, Elem.DigestValue);
					byte [] baDigest = OpenNETCF.Security.Cryptography.NativeMethods.Format.GetB64(digValElem.InnerText);

					XmlElement refdElem = LameXpath.SelectSingleNode(uriId, sigDoc);
					XmlDocument xdRefdElem = new XmlDocument();
					refdName = refdElem.LocalName; //for debug visibility
					xdRefdElem.LoadXml(refdElem.OuterXml);
					//not reusable
					xc = new XmlCanonicalizer(comments, exclusive);
					//MemoryStream ms = (MemoryStream) xc.Canonicalize(refdElem);
					ms = (MemoryStream) xc.Canonicalize(xdRefdElem);
					baMs = new byte[ms.Length];
					ms.Read(baMs, 0, baMs.Length);
					byte [] baHash = shaCsp.ComputeHash(baMs);
					try
					{
						OpenNETCF.Security.Cryptography.NativeMethods.Format.SameBytes(baDigest, baHash);
					}
					catch(Exception ex)
					{
						throw new Exception(refdName + ":" + ex.Message, ex);
					}
				}
			}
			finally
			{
				//ClearPassword = null;
				SigObj = null;
			}
		}
Esempio n. 5
0
		public override byte [] DecryptValue(byte [] keyWrap)
		{
			//1. Check if the length of the cipher text is reasonable given the key type. 
			//It must be 40 bytes for a 168 bit key and either 32, 40, or 48 bytes for a 128, 192, or 256 bit key. 
			//If the length is not supported or inconsistent with the algorithm for which the key is intended, return error. 
			if(keyWrap.Length < 40)
			{
				throw new Exception("kw-tripledes must be 40 bytes for TripleDES key");
			}

			//2. Decrypt the cipher text with TRIPLEDES in CBC mode using the KEK and an initialization vector (IV) of 0x4adda22c79e82105. Call the output TEMP3. 
			_tdcsp.IV = kwIv;
			TripleDesNoPadding tdnp = new TripleDesNoPadding(_tdcsp);
			byte [] temp3 = tdnp.Decrypt(keyWrap);

			//3. Reverse the order of the octets in TEMP3 and call the result TEMP2. 
			byte [] temp2 = (byte []) temp3.Clone();
			Array.Reverse(temp2, 0, temp2.Length);
			//4. Decompose TEMP2 into IV, the first 8 octets, and TEMP1, the remaining octets. 
			byte [] temp1iv = new byte[_tdcsp.IV.Length];
			Array.Copy(temp2, 0, temp1iv, 0, temp1iv.Length);
			byte [] temp1 = new byte [temp2.Length - temp1iv.Length];
			Array.Copy(temp2, temp1iv.Length, temp1, 0, temp1.Length);

			//5. Decrypt TEMP1 using TRIPLEDES in CBC mode using the KEK and the IV found in the previous step. Call the result WKCKS.
			_tdcsp.IV = temp1iv;
			byte [] WKCKS = tdnp.Decrypt(temp1);

			//6. Decompose WKCKS. CKS is the last 8 octets and WK, the wrapped key, are those octets before the CKS. 
			byte [] CKS = new byte[8];
			byte [] WK = new byte[WKCKS.Length - 8];
			Array.Copy(WKCKS, WKCKS.Length - 8, CKS, 0, 8);
			Array.Copy(WKCKS, 0, WK, 0, WKCKS.Length - 8);

			//7. Calculate a CMS key checksum (section 5.6.1) over the WK and compare with the CKS extracted in the above step. If they are not equal, return error. 
			SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider();
			byte [] CMS = sha1.ComputeHash(WK);

			//check hash
			for(int i=0; i<CKS.Length; i++)
			{
				if(CKS[i] != CMS[i])
					throw new Exception("KeyWrap CheckSum failed");
			}
								
			//8. WK is the wrapped key, now extracted for use in data decryption. 
			return WK;
		}