Пример #1
0
 public byte[] DecryptKeyExchange(byte[] data)
 {
     if (m_Disposed)
     {
         throw new CryptographicException("The key has been disposed");
     }
     if (m_NeedsHack)
     {
         // get the key handle
         IntPtr key = GetHandle(m_Key);
         // decrypt the data
         byte[] dec = (byte[])data.Clone();
         Array.Reverse(dec);                 // big endian to little endian
         int size = data.Length;
         if (SspiProvider.CryptDecrypt(key, 0, 1, 0, dec, ref size) == 0)
         {
             throw new CryptographicException("Unable to decrypt the key exchange [" + Marshal.GetLastWin32Error() + "].");
         }
         byte[] ret = new byte[size];
         Buffer.BlockCopy(dec, 0, ret, 0, size);
         return(ret);
     }
     else
     {
         return(m_Key.Decrypt(data, false));
     }
 }
        /// <summary>
        /// Transforms the specified region of the input byte array and copies the resulting transform to the specified region of the output byte array.
        /// </summary>
        /// <param name="inputBuffer">The input for which to compute the transform.</param>
        /// <param name="inputOffset">The offset into the input byte array from which to begin using data.</param>
        /// <param name="inputCount">The number of bytes in the input byte array to use as data.</param>
        /// <param name="outputBuffer">The output to which to write the transform.</param>
        /// <param name="outputOffset">The offset into the output byte array from which to begin writing data.</param>
        /// <returns>The number of bytes written.</returns>
        /// <exception cref="ObjectDisposedException">The object has been disposed.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="inputBuffer"/> or <paramref name="outputBuffer"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception>
        /// <exception cref="ArgumentOutOfRangeException">One of the specified offsets or lengths is invalid.</exception>
        /// <exception cref="CryptographicException">An error occurs while transforming the specified data.</exception>
        public int TransformBlock(byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
        {
            if (m_Key == null)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }
            if (inputBuffer == null || outputBuffer == null)
            {
                throw new ArgumentNullException();
            }
            if (inputCount < 0 || inputOffset < 0 || outputOffset < 0 || inputOffset + inputCount > inputBuffer.Length)
            {
                throw new ArgumentOutOfRangeException();
            }
            int length = inputCount;

            if (m_Method == CryptoMethod.Encrypt)
            {
                if (SspiProvider.CryptEncrypt(m_Key.Handle, 0, 0, 0, null, ref length, 0) == 0)
                {
                    throw new CryptographicException("Could not encrypt data.");
                }
                if (outputBuffer.Length - outputOffset < length)
                {
                    throw new ArgumentOutOfRangeException();
                }
                Buffer.BlockCopy(inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
                length = inputCount;
                GCHandle h = GCHandle.Alloc(outputBuffer, GCHandleType.Pinned);
                try {
                    if (SspiProvider.CryptEncrypt(m_Key.Handle, 0, 0, 0, new IntPtr(h.AddrOfPinnedObject().ToInt64() + outputOffset), ref length, outputBuffer.Length - outputOffset) == 0)
                    {
                        throw new CryptographicException("Could not encrypt data.");
                    }
                } finally {
                    h.Free();
                }
            }
            else                 // decrypt
            {
                byte[] orgCopy = new byte[inputCount];
                Buffer.BlockCopy(inputBuffer, inputOffset, orgCopy, 0, inputCount);
                if (SspiProvider.CryptDecrypt(m_Key.Handle, 0, 0, 0, orgCopy, ref length) == 0)
                {
                    throw new CryptographicException("Could not decrypt data.");
                }
                if (length > outputBuffer.Length - outputOffset)
                {
                    throw new ArgumentOutOfRangeException();
                }
                Buffer.BlockCopy(orgCopy, 0, outputBuffer, outputOffset, length);
            }
            return(length);
        }
        /// <summary>
        /// Transforms the specified region of the specified byte array.
        /// </summary>
        /// <param name="inputBuffer">The input for which to compute the transform.</param>
        /// <param name="inputOffset">The offset into the byte array from which to begin using data.</param>
        /// <param name="inputCount">The number of bytes in the byte array to use as data.</param>
        /// <returns>The computed transform.</returns>
        /// <exception cref="ObjectDisposedException">The object has been disposed.</exception>
        /// <exception cref="ArgumentNullException"><paramref name="inputBuffer"/> is a null reference (<b>Nothing</b> in Visual Basic).</exception>
        /// <exception cref="ArgumentOutOfRangeException">The combination of offset and length is invalid.</exception>
        /// <exception cref="CryptographicException">An error occurs while transforming the specified data.</exception>
        public byte[] TransformFinalBlock(byte[] inputBuffer, int inputOffset, int inputCount)
        {
            if (m_Key == null)
            {
                throw new ObjectDisposedException(this.GetType().FullName);
            }
            if (inputBuffer == null)
            {
                throw new ArgumentNullException();
            }
            if (inputCount < 0 || inputOffset < 0 || inputOffset + inputCount > inputBuffer.Length)
            {
                throw new ArgumentOutOfRangeException();
            }
            int length = inputCount;

            byte[] ret;
            if (m_Method == CryptoMethod.Encrypt)
            {
                if (SspiProvider.CryptEncrypt(m_Key.Handle, 0, 1, 0, null, ref length, 0) == 0)
                {
                    throw new CryptographicException("Could not encrypt data.");
                }
                ret = new byte[length];
                Buffer.BlockCopy(inputBuffer, inputOffset, ret, 0, inputCount);
                length = inputCount;
                if (SspiProvider.CryptEncrypt(m_Key.Handle, 0, 1, 0, ret, ref length, ret.Length) == 0)
                {
                    throw new CryptographicException("Could not encrypt data.");
                }
            }
            else                 // decrypt
            {
                byte[] orgCopy = new byte[inputCount];
                Buffer.BlockCopy(inputBuffer, inputOffset, orgCopy, 0, inputCount);
                if (SspiProvider.CryptDecrypt(m_Key.Handle, 0, 1, 0, orgCopy, ref length) == 0)
                {
                    throw new CryptographicException("Could not decrypt data.");
                }
                ret = new byte[length];
                Buffer.BlockCopy(orgCopy, 0, ret, 0, length);
            }
            return(ret);
        }