/// <summary>
        /// Read the protected data and return it protected with a sequence
        /// of bytes generated by a random stream. The object's data will be
        /// invisible in process memory only if the object has been initialized
        /// using a <c>XorredBuffer</c>. If no <c>XorredBuffer</c> has been used
        /// or the binary has been read once already (in plain-text), the
        /// operation won't be secure and the protected string will be visible
        /// in process memory.
        /// </summary>
        /// <param name="crsRandomSource">Random number source.</param>
        /// <returns>Protected data.</returns>
        /// <exception cref="System.ArgumentNullException">Thrown if the input
        /// parameter is <c>null</c>.</exception>
        public byte[] ReadXorredData(CryptoRandomStream crsRandomSource)
        {
            Debug.Assert(crsRandomSource != null);
            if (crsRandomSource == null)
            {
                throw new ArgumentNullException("crsRandomSource");
            }

            if (m_xbEncrypted != null)
            {
                uint   uLen      = m_xbEncrypted.Length;
                byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
                return(m_xbEncrypted.ChangeKey(randomPad));
            }
            else
            {
                byte[] pbData = ReadData();
                uint   uLen   = (uint)pbData.Length;

                byte[] randomPad = crsRandomSource.GetRandomBytes(uLen);
                Debug.Assert(randomPad.Length == uLen);

                for (uint i = 0; i < uLen; i++)
                {
                    pbData[i] ^= randomPad[i];
                }

                return(pbData);
            }
        }
        public void ChangeKey()
        {
            // arrange
            var data = new byte[] { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 };
            var firstPad = new byte[] { 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 };
            var protectedData = new byte[data.Length];
            for (var i = 0; i < data.Length; i++)
            {
                protectedData[i] = (byte) (data[i] ^ firstPad[i]);
            }
            var xb = new XorredBuffer(protectedData, firstPad);
            var secondPad = new byte[] { 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27 };

            // act
            var actual = xb.ChangeKey(secondPad);

            // assert
            Assert.AreEqual(data.Length, actual.Length);
            Assert.AreSame(protectedData, actual);
            for (var i = 0; i < data.Length; i++ )
            {
                Assert.AreEqual(0x20, actual[i]);
            }
        }