///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // Encrypt a ticket /// <include file='doc\FormsAuthentication.uex' path='docs/doc[@for="FormsAuthentication.Encrypt"]/*' /> /// <devdoc> /// Given a FormsAuthenticationTicket, this /// method produces a string containing an encrypted authentication ticket suitable /// for use in an HTTP cookie. /// </devdoc> public static String Encrypt(FormsAuthenticationTicket ticket) { if (ticket == null) { throw new ArgumentNullException("ticket"); } Initialize(); ////////////////////////////////////////////////////////////////////// // Step 1: Make it into a binary blob byte [] bBlob = MakeTicketIntoBinaryBlob(ticket); if (bBlob == null) { return(null); } if (_Protection == FormsProtectionEnum.None) { return(MachineKey.ByteArrayToHexString(bBlob, 0)); } ////////////////////////////////////////////////////////////////////// // Step 2: Get the MAC and add to the blob if (_Protection == FormsProtectionEnum.All || _Protection == FormsProtectionEnum.Validation) { byte [] bMac = MachineKey.HashData(bBlob, null, 0, bBlob.Length); if (bMac == null) { return(null); } Trace("Encrypt: MAC length is: " + bMac.Length); byte [] bAll = new byte[bMac.Length + bBlob.Length]; Buffer.BlockCopy(bBlob, 0, bAll, 0, bBlob.Length); Buffer.BlockCopy(bMac, 0, bAll, bBlob.Length, bMac.Length); if (_Protection == FormsProtectionEnum.Validation) { return(MachineKey.ByteArrayToHexString(bAll, 0)); } bBlob = bAll; } ////////////////////////////////////////////////////////////////////// // Step 3: Do the actual encryption bBlob = MachineKey.EncryptOrDecryptData(true, bBlob, null, 0, bBlob.Length); return(MachineKey.ByteArrayToHexString(bBlob, bBlob.Length)); }
///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////// // Decrypt and get the auth ticket /// <include file='doc\FormsAuthentication.uex' path='docs/doc[@for="FormsAuthentication.Decrypt"]/*' /> /// <devdoc> /// <para>Given an encrypted authenitcation ticket as /// obtained from an HTTP cookie, this method returns an instance of a /// FormsAuthenticationTicket class.</para> /// </devdoc> public static FormsAuthenticationTicket Decrypt(String encryptedTicket) { if (encryptedTicket == null || encryptedTicket.Length == 0) { throw new ArgumentException(HttpRuntime.FormatResourceString(SR.InvalidArgumentValue, "encryptedTicket")); } Initialize(); Trace("Decrypting cookie: " + encryptedTicket); byte [] bBlob = MachineKey.HexStringToByteArray(encryptedTicket); if (bBlob == null || bBlob.Length < 1) { throw new ArgumentException(HttpRuntime.FormatResourceString(SR.InvalidArgumentValue, "encryptedTicket")); } if (_Protection == FormsProtectionEnum.All || _Protection == FormsProtectionEnum.Encryption) { bBlob = MachineKey.EncryptOrDecryptData(false, bBlob, null, 0, bBlob.Length); if (bBlob == null) { return(null); } } if (_Protection == FormsProtectionEnum.All || _Protection == FormsProtectionEnum.Validation) { ////////////////////////////////////////////////////////////////////// // Step 2: Get the MAC: Last MAC_LENGTH bytes if (bBlob.Length <= MAC_LENGTH) { return(null); } byte [] bTicket = new byte[bBlob.Length - MAC_LENGTH]; Buffer.BlockCopy(bBlob, 0, bTicket, 0, bTicket.Length); byte [] bMac = MachineKey.HashData(bTicket, null, 0, bTicket.Length); ////////////////////////////////////////////////////////////////////// // Step 3: Make sure the MAC is correct if (bMac == null) { Trace("Decrypting cookie failed to get the MAC."); return(null); } if (bMac.Length != MAC_LENGTH) { Trace("Decrypting cookie failed due to bad MAC length: " + bMac.Length); return(null); } for (int iter = 0; iter < MAC_LENGTH; iter++) { if (bMac[iter] != bBlob[bTicket.Length + iter]) { Trace("Incorrect byte at " + iter + ", byte1: " + ((int)bMac[iter]) + ", byte2: " + ((int)bBlob[bTicket.Length + iter])); return(null); } } bBlob = bTicket; } ////////////////////////////////////////////////////////////////////// // Step 4: Change binary ticket to managed struct int iSize = ((bBlob.Length > 4096) ? 4096 : bBlob.Length); StringBuilder name = new StringBuilder(iSize); StringBuilder data = new StringBuilder(iSize); StringBuilder path = new StringBuilder(iSize); byte [] pBin = new byte[2]; long [] pDates = new long[2]; int iRet = UnsafeNativeMethods.CookieAuthParseTicket(bBlob, bBlob.Length, name, iSize, data, iSize, path, iSize, pBin, pDates); if (iRet != 0) { return(null); } return(new FormsAuthenticationTicket((int)pBin[0], name.ToString(), DateTime.FromFileTime(pDates[0]), DateTime.FromFileTime(pDates[1]), (bool)(pBin[1] != 0), data.ToString(), path.ToString())); }