Как я могу зашифровать эти методы сохранения / загрузки BinaryFormatter в c #? [Дубликат]

Конечно, есть много таких подходов, как синхронный запрос, обещание, но из моего опыта я думаю, что вы должны использовать подход обратного вызова. Естественно, что асинхронное поведение Javascript. Итак, ваш фрагмент кода можно переписать немного иначе:

function foo() {
    var result;

    $.ajax({
        url: '...',
        success: function(response) {
            myCallback(response);
        }
    });

    return result;
}

function myCallback(response) {
    // Does something.
}
2
задан geedubb 1 March 2015 в 15:49
поделиться

1 ответ

Вместо перехода на byte[] в качестве промежуточного шага при переходе к различным объектам потока вы можете объединить несколько потоков вместе, передавая результат от одного к входу другого.

Этот подход имеет смысл здесь , поскольку вы цепляетесь вместе

Двоичная сериализация => Шифрование => Запись в файл.

С учетом этого вы можете изменить ConvertObjectEmByte на что-то вроде:

public static void WriteObjectToStream(Stream outputStream, Object obj)
{
    if (object.ReferenceEquals(null, obj))
    {
        return;
    }

    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(outputStream, obj);
}

и аналогичным образом ConvertByteEmObject может стать:

public static object ReadObjectFromStream(Stream inputStream)
{
    BinaryFormatter binForm = new BinaryFormatter();
    object obj = binForm.Deserialize(inputStream);
    return obj;
}

Чтобы добавить шифрование / дешифрование, мы можем писать функции, которые создают объекты CryptoStream, которые мы можем связать с этими двоичными функции сериализации. Мои приведенные ниже функции ниже немного отличаются от функций Encrypt / Decrypt в статье, с которой вы связаны, потому что IV (вектор инициализации) теперь генерируется случайным образом и записывается в поток (и читается из потока на другом конце). Важно, чтобы IV был уникальным для каждого фрагмента данных, которые вы шифруете для обеспечения безопасности, и вы также должны использовать генератор случайных чисел, предназначенный для криптографических целей, таких как RNGCryptoServiceProvider , а не генератор псевдослучайных чисел например Random.

public static CryptoStream CreateEncryptionStream(byte[] key, Stream outputStream)
{
    byte[] iv = new byte[ivSize];

    using (var rng = new RNGCryptoServiceProvider())
    {
        // Using a cryptographic random number generator
        rng.GetNonZeroBytes(iv);
    }

    // Write IV to the start of the stream
    outputStream.Write(iv, 0, iv.Length);

    Rijndael rijndael = new RijndaelManaged();
    rijndael.KeySize = keySize;

    CryptoStream encryptor = new CryptoStream(
        outputStream,
        rijndael.CreateEncryptor(key, iv),
        CryptoStreamMode.Write);
    return encryptor;
}

public static CryptoStream CreateDecryptionStream(byte[] key, Stream inputStream)
{
    byte[] iv = new byte[ivSize];

    if (inputStream.Read(iv, 0, iv.Length) != iv.Length)
    {
        throw new ApplicationException("Failed to read IV from stream.");
    }

    Rijndael rijndael = new RijndaelManaged();
    rijndael.KeySize = keySize;

    CryptoStream decryptor = new CryptoStream(
        inputStream,
        rijndael.CreateDecryptor(key, iv),
        CryptoStreamMode.Read);
    return decryptor;
}

Наконец, мы можем склеить его вместе:

byte[] key = Convert.FromBase64String(cryptoKey);

using (FileStream file = new FileStream(Environment.CurrentDirectory + @"\class.dat", FileMode.Create))
using (CryptoStream cryptoStream = CreateEncryptionStream(key, file))
{
    WriteObjectToStream(cryptoStream, myVarClass);
}

MyClass newMyVarClass;
using (FileStream file = new FileStream(Environment.CurrentDirectory + @"\class.dat", FileMode.Open))
using (CryptoStream cryptoStream = CreateDecryptionStream(key, file))
{
    newMyVarClass = (MyClass)ReadObjectFromStream(cryptoStream);
}

Обратите внимание, что мы передаем объект потока file в CreateEncryptionStreamCreateDecryptionStream), а затем передать объект cryptoStream в WriteObjectToStreamReadObjectfromStream). Вы также заметите, что потоки ограничены внутри блоков using, так что они будут автоматически очищены, когда мы закончим с ними.

Вот полная тестовая программа:

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using System.Security.Cryptography;

namespace CryptoStreams
{
    class Program
    {
        [Serializable]
        public class MyClass
        {
            public string TestValue
            {
                get;
                set;
            }

            public int SomeInt
            {
                get;
                set;
            }
        }

        public static void WriteObjectToStream(Stream outputStream, Object obj)
        {
            if (object.ReferenceEquals(null, obj))
            {
                return;
            }

            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(outputStream, obj);
        }

        public static object ReadObjectFromStream(Stream inputStream)
        {
            BinaryFormatter binForm = new BinaryFormatter();
            object obj = binForm.Deserialize(inputStream);
            return obj;
        }

        private const string cryptoKey =
            "Q3JpcHRvZ3JhZmlhcyBjb20gUmluamRhZWwgLyBBRVM=";
        private const int keySize = 256;
        private const int ivSize = 16; // block size is 128-bit

        public static CryptoStream CreateEncryptionStream(byte[] key, Stream outputStream)
        {
            byte[] iv = new byte[ivSize];

            using (var rng = new RNGCryptoServiceProvider())
            {
                // Using a cryptographic random number generator
                rng.GetNonZeroBytes(iv);
            }

            // Write IV to the start of the stream
            outputStream.Write(iv, 0, iv.Length);

            Rijndael rijndael = new RijndaelManaged();
            rijndael.KeySize = keySize;

            CryptoStream encryptor = new CryptoStream(
                outputStream,
                rijndael.CreateEncryptor(key, iv),
                CryptoStreamMode.Write);
            return encryptor;
        }

        public static CryptoStream CreateDecryptionStream(byte[] key, Stream inputStream)
        {
            byte[] iv = new byte[ivSize];

            if (inputStream.Read(iv, 0, iv.Length) != iv.Length)
            {
                throw new ApplicationException("Failed to read IV from stream.");
            }

            Rijndael rijndael = new RijndaelManaged();
            rijndael.KeySize = keySize;

            CryptoStream decryptor = new CryptoStream(
                inputStream,
                rijndael.CreateDecryptor(key, iv),
                CryptoStreamMode.Read);
            return decryptor;
        }

        static void Main(string[] args)
        {
            MyClass myVarClass = new MyClass
            {
                SomeInt = 1234,
                TestValue = "Hello"
            };

            byte[] key = Convert.FromBase64String(cryptoKey);

            using (FileStream file = new FileStream(Environment.CurrentDirectory + @"\class.dat", FileMode.Create))
            {
                using (CryptoStream cryptoStream = CreateEncryptionStream(key, file))
                {
                    WriteObjectToStream(cryptoStream, myVarClass);
                }
            }

            MyClass newMyVarClass;
            using (FileStream file = new FileStream(Environment.CurrentDirectory + @"\class.dat", FileMode.Open))
            using (CryptoStream cryptoStream = CreateDecryptionStream(key, file))
            {
                newMyVarClass = (MyClass)ReadObjectFromStream(cryptoStream);
            }

            Console.WriteLine("newMyVarClass.SomeInt: {0}; newMyVarClass.TestValue: {1}",
                newMyVarClass.SomeInt,
                newMyVarClass.TestValue);
        }
    }
}
5
ответ дан softwariness 25 August 2018 в 21:17
поделиться
Другие вопросы по тегам:

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