/// <summary> /// Serialize the cookie container into a byte array. /// </summary> /// <returns>Byte array that represents the Cookie Container</returns> public byte[] Serialize(CookieContainer cookieContainer) { // First turn the encryptedSymmetricKey.Length into a byte array byte[] keyLength = DataBitsConverter.ToBytes(cookieContainer.EncryptedSymmetricKey.Length); // Allocate the total buffer required. int bufferSize = keyLength.Length + cookieContainer.EncryptedSymmetricKey.Length + cookieContainer.IV.Length + cookieContainer.EncryptedCookie.Length; byte[] buffer = new byte[bufferSize]; // Copy SymmetricKeyLength to the buffer. Array.Copy(keyLength, buffer, keyLength.Length); // Keep track of the next available space in the buffer. int index = keyLength.Length; // Copy the encrypted symmetric key to the buffer. Array.Copy(cookieContainer.EncryptedSymmetricKey, 0, buffer, index, cookieContainer.EncryptedSymmetricKey.Length); index += cookieContainer.EncryptedSymmetricKey.Length; // Copy the IV to the buffer Array.Copy(cookieContainer.IV, 0, buffer, index, cookieContainer.IV.Length); index += cookieContainer.IV.Length; // The rest of the buffer contains the encrypted SCT Cookie. Array.Copy(cookieContainer.EncryptedCookie, 0, buffer, index, cookieContainer.EncryptedCookie.Length); return(buffer); }
/// <summary> /// Turns a byte array back into a CookieContainer. /// </summary> /// <param name="rsaKey">The protection RSA key to decrypt the symmetric key.</param> /// <param name="aesAlg">The symmetric key algorithm to use to decrypt the cookie block.</param> /// <param name="data">The byte array to deserialize.</param> /// <returns>The deserialized cookie container instance.</returns> public CookieContainer Deserialize(RSACryptoServiceProvider rsaKey, RijndaelManaged aesAlg, byte[] data) { CookieContainer cookieContainer = new CookieContainer(rsaKey, aesAlg); // Length of the IV according to the AES algorithm (in bytes). int ivLength = aesAlg.BlockSize / 8; // Determine how much buffer to read to retrieve the symmetric key. int symmetricKeyLength = DataBitsConverter.ToInt(data, 0, sizeof(int)); // Perform some basic data validation if (symmetricKeyLength <= 0) { throw new InvalidOperationException("symmetricKeyLength must be greater than zero."); } checked { if (sizeof(int) + symmetricKeyLength + ivLength > data.Length) { throw new InvalidOperationException("symmetricKeyLength + encryptedSymmetricKey + IV (in bytes) exceeds the data buffer length."); } } // Use an index to track the next byte to read in the data buffer. int index = sizeof(int); // Retrieve the encrypted symmetric key. cookieContainer.EncryptedSymmetricKey = new byte[symmetricKeyLength]; Array.Copy(data, index, cookieContainer.EncryptedSymmetricKey, 0, symmetricKeyLength); index += symmetricKeyLength; // Retrieve the IV. cookieContainer.IV = new byte[ivLength]; Array.Copy(data, index, cookieContainer.IV, 0, ivLength); index += ivLength; // Retrieve the encrypted cookie. cookieContainer.EncryptedCookie = new byte[data.Length - index]; Array.Copy(data, index, cookieContainer.EncryptedCookie, 0, data.Length - index); // Re-create the encryptor / decryptor with the new symmetric key and IV. cookieContainer.CreateCryptoTransformers(); return(cookieContainer); }