HttpContext. Объекты с ASP.NET MVC

Другие ответы здесь работают нормально, но AES - более безопасный и современный алгоритм шифрования. Это класс, который я получил несколько лет назад для выполнения шифрования AES, который я со временем модифицировал, чтобы сделать его более удобным для веб-приложений (например, я создал методы шифрования / дешифрования, которые работают с дружественной к URL-адресам строкой). В нем также есть методы, работающие с байтовыми массивами.

ПРИМЕЧАНИЕ: вы должны использовать разные значения в массивах Key (32 байта) и Vector (16 байтов)! Вы бы не хотели, чтобы кто-то выяснил ваши ключи, просто предположив, что вы использовали этот код как есть! Все, что вам нужно сделать, это изменить некоторые числа (должно быть https://www.random.org/bytes/ , чтобы легко сгенерировать новый набор:

Использование просто: просто создайте экземпляр класса, а затем вызовите (обычно) EncryptToString (строка StringToEncrypt) и DecryptString (строка StringToDecrypt) как методы. Нет ничего проще (или безопаснее), если у вас есть этот класс.


using System;
using System.Data;
using System.Security.Cryptography;
using System.IO;


public class SimpleAES
{
    // Change these keys
    private byte[] Key = __Replace_Me__({ 123, 217, 19, 11, 24, 26, 85, 45, 114, 184, 27, 162, 37, 112, 222, 209, 241, 24, 175, 144, 173, 53, 196, 29, 24, 26, 17, 218, 131, 236, 53, 209 });

    // a hardcoded IV should not be used for production AES-CBC code
    // IVs should be unpredictable per ciphertext
    private byte[] Vector = __Replace_Me__({ 146, 64, 191, 111, 23, 3, 113, 119, 231, 121, 2521, 112, 79, 32, 114, 156 });


    private ICryptoTransform EncryptorTransform, DecryptorTransform;
    private System.Text.UTF8Encoding UTFEncoder;

    public SimpleAES()
    {
        //This is our encryption method
        RijndaelManaged rm = new RijndaelManaged();

        //Create an encryptor and a decryptor using our encryption method, key, and vector.
        EncryptorTransform = rm.CreateEncryptor(this.Key, this.Vector);
        DecryptorTransform = rm.CreateDecryptor(this.Key, this.Vector);

        //Used to translate bytes to text and vice versa
        UTFEncoder = new System.Text.UTF8Encoding();
    }

    /// -------------- Two Utility Methods (not used but may be useful) -----------
    /// Generates an encryption key.
    static public byte[] GenerateEncryptionKey()
    {
        //Generate a Key.
        RijndaelManaged rm = new RijndaelManaged();
        rm.GenerateKey();
        return rm.Key;
    }

    /// Generates a unique encryption vector
    static public byte[] GenerateEncryptionVector()
    {
        //Generate a Vector
        RijndaelManaged rm = new RijndaelManaged();
        rm.GenerateIV();
        return rm.IV;
    }


    /// ----------- The commonly used methods ------------------------------    
    /// Encrypt some text and return a string suitable for passing in a URL.
    public string EncryptToString(string TextValue)
    {
        return ByteArrToString(Encrypt(TextValue));
    }

    /// Encrypt some text and return an encrypted byte array.
    public byte[] Encrypt(string TextValue)
    {
        //Translates our text value into a byte array.
        Byte[] bytes = UTFEncoder.GetBytes(TextValue);

        //Used to stream the data in and out of the CryptoStream.
        MemoryStream memoryStream = new MemoryStream();

        /*
         * We will have to write the unencrypted bytes to the stream,
         * then read the encrypted result back from the stream.
         */
        #region Write the decrypted value to the encryption stream
        CryptoStream cs = new CryptoStream(memoryStream, EncryptorTransform, CryptoStreamMode.Write);
        cs.Write(bytes, 0, bytes.Length);
        cs.FlushFinalBlock();
        #endregion

        #region Read encrypted value back out of the stream
        memoryStream.Position = 0;
        byte[] encrypted = new byte[memoryStream.Length];
        memoryStream.Read(encrypted, 0, encrypted.Length);
        #endregion

        //Clean up.
        cs.Close();
        memoryStream.Close();

        return encrypted;
    }

    /// The other side: Decryption methods
    public string DecryptString(string EncryptedString)
    {
        return Decrypt(StrToByteArray(EncryptedString));
    }

    /// Decryption when working with byte arrays.    
    public string Decrypt(byte[] EncryptedValue)
    {
        #region Write the encrypted value to the decryption stream
        MemoryStream encryptedStream = new MemoryStream();
        CryptoStream decryptStream = new CryptoStream(encryptedStream, DecryptorTransform, CryptoStreamMode.Write);
        decryptStream.Write(EncryptedValue, 0, EncryptedValue.Length);
        decryptStream.FlushFinalBlock();
        #endregion

        #region Read the decrypted value from the stream.
        encryptedStream.Position = 0;
        Byte[] decryptedBytes = new Byte[encryptedStream.Length];
        encryptedStream.Read(decryptedBytes, 0, decryptedBytes.Length);
        encryptedStream.Close();
        #endregion
        return UTFEncoder.GetString(decryptedBytes);
    }

    /// Convert a string to a byte array.  NOTE: Normally we'd create a Byte Array from a string using an ASCII encoding (like so).
    //      System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding();
    //      return encoding.GetBytes(str);
    // However, this results in character values that cannot be passed in a URL.  So, instead, I just
    // lay out all of the byte values in a long string of numbers (three per - must pad numbers less than 100).
    public byte[] StrToByteArray(string str)
    {
        if (str.Length == 0)
            throw new Exception("Invalid string value in StrToByteArray");

        byte val;
        byte[] byteArr = new byte[str.Length / 3];
        int i = 0;
        int j = 0;
        do
        {
            val = byte.Parse(str.Substring(i, 3));
            byteArr[j++] = val;
            i += 3;
        }
        while (i < str.Length);
        return byteArr;
    }

    // Same comment as above.  Normally the conversion would use an ASCII encoding in the other direction:
    //      System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();
    //      return enc.GetString(byteArr);    
    public string ByteArrToString(byte[] byteArr)
    {
        byte val;
        string tempStr = "";
        for (int i = 0; i <= byteArr.GetUpperBound(0); i++)
        {
            val = byteArr[i];
            if (val < (byte)10)
                tempStr += "00" + val.ToString();
            else if (val < (byte)100)
                tempStr += "0" + val.ToString();
            else
                tempStr += val.ToString();
        }
        return tempStr;
    }
}

33
задан Ryan Hoffman 15 July 2009 в 22:19
поделиться

3 ответа

Ваш вопрос задает несколько вопросов, но я думаю, что пункт №1 - это тот ответ, который вы ищете.

  1. Можно ли использовать Context.Items для кэширования для каждого запроса? Да. Если вашим критерием является процесс, на запрос, на каждую машину в веб-ферме, тогда Context.Items дает вам это.

  2. Сложно ли тестировать Context.Items ? Что касается тестируемости, я бы спрятал Context.Items за каким-то интерфейсом. Таким образом, вы получаете возможности модульного тестирования без необходимости напрямую ссылаться на Context.Items . В противном случае, что вам нужно проверить для Context.Items ? Что фреймворк будет хранить и извлекать значения? Пусть ваш код не знает System.Web , и вы станете счастливым туристом.

  3. Выживет ли Context.Items RedirectToAction ? Нет. Ваш тест недействителен. Он устанавливает «Hello, world» на каждый веб-запрос, и ваш тест охватывает два веб-запроса. Первый - когда вызывается действие Index. Второй - когда вызывается действие RedirectToAction (это HTTP 302). Чтобы это не удалось, установите новое значение в действии «Индекс» и проверьте, сохраняется ли оно в действии «О программе».

38
ответ дан 27 November 2019 в 18:34
поделиться

Используйте словарь TempData Dictionary, он предназначен в основном для хранения объектов между перенаправлениями действий:

public ActionResult Index()
{
    TempData.Add("Test", "Hello world");
    return RedirectToAction("About");
}

public ActionResult About()
{
    ViewData["Test"] = TempData["Test"];
    return View();
}

Затем извлеките значение в вашем представлении:

<%=ViewData["Test"] %>
3
ответ дан 27 November 2019 в 18:34
поделиться

Я провел тест, и TempData действительно взрывается при отключенном состоянии сеанса. Мой единственный совет - не хранить сам объект во временных данных, а хранить простые типизированные поля, как было предложено. Поскольку вы не сериализуете деревья объектов, это не должно сильно влиять на производительность вне процесса.

1
ответ дан 27 November 2019 в 18:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: