/// <summary>
        /// Decrypts the message using RSA encryption.
        /// </summary>
        private ArraySegment <byte> Rsa_Decrypt(
            ArraySegment <byte> dataToDecrypt,
            ArraySegment <byte> headerToCopy,
            X509Certificate2 encryptingCertificate,
            RsaUtils.Padding padding)
        {
            RSA rsa = null;

            try
            {
                // get the encrypting key.
                rsa = encryptingCertificate.GetRSAPrivateKey();
                if (rsa == null)
                {
                    throw ServiceResultException.Create(StatusCodes.BadSecurityChecksFailed, "No private key for certificate.");
                }

                int inputBlockSize  = RsaUtils.GetCipherTextBlockSize(rsa, padding);
                int outputBlockSize = RsaUtils.GetPlainTextBlockSize(rsa, padding);

                // verify the input data is the correct block size.
                if (dataToDecrypt.Count % inputBlockSize != 0)
                {
                    Utils.Trace("Message is not an integral multiple of the block size. Length = {0}, BlockSize = {1}.", dataToDecrypt.Count, inputBlockSize);
                }

                byte[] decryptedBuffer = BufferManager.TakeBuffer(SendBufferSize, "Rsa_Decrypt");
                Array.Copy(headerToCopy.Array, headerToCopy.Offset, decryptedBuffer, 0, headerToCopy.Count);
                RSAEncryptionPadding rsaPadding = RsaUtils.GetRSAEncryptionPadding(padding);

                using (MemoryStream ostrm = new MemoryStream(
                           decryptedBuffer,
                           headerToCopy.Count,
                           decryptedBuffer.Length - headerToCopy.Count))
                {
                    // decrypt body.
                    byte[] input = new byte[inputBlockSize];

                    for (int ii = dataToDecrypt.Offset; ii < dataToDecrypt.Offset + dataToDecrypt.Count; ii += inputBlockSize)
                    {
                        Array.Copy(dataToDecrypt.Array, ii, input, 0, input.Length);
                        byte[] plainText = rsa.Decrypt(input, rsaPadding);
                        ostrm.Write(plainText, 0, plainText.Length);
                    }
                }

                // return buffers.
                return(new ArraySegment <byte>(decryptedBuffer, 0, (dataToDecrypt.Count / inputBlockSize) * outputBlockSize + headerToCopy.Count));
            }
            finally
            {
                RsaUtils.RSADispose(rsa);
            }
        }