Encrypt .NET binary serialization stream

前端 未结 2 975
独厮守ぢ
独厮守ぢ 2021-01-06 09:19

I\'m studying encryption in C# and I\'m having trouble. I have some Rijndael encryption code and it\'s working perfectly with strings. But now I\'m studying serialization an

2条回答
  •  傲寒
    傲寒 (楼主)
    2021-01-06 09:50

    I'm not sure whether the .Net Library had changed or just the code is wrong. I can't directly run the code written by softwariness. Since that, I changed the code based on the answer so that it can be used correctly. Here's an example.

    public class CryptoSerialization
    {
        public static void WriteObjectToStream(Stream outputStream, object obj)
        {
            if (obj is null) throw new ArgumentNullException("obj can't be null");
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(outputStream, obj);
        }
    
        public static object ReadObjectFromStream(Stream inputStream)
        {
            BinaryFormatter bf = new BinaryFormatter();
            return bf.Deserialize(inputStream);
        }
    
        public static CryptoStream CreateEncryptionStream(Stream outputStream, byte[] Key, byte[] IV)
        {
            Rijndael rijndael = new RijndaelManaged();
    
            return new CryptoStream(outputStream, rijndael.CreateEncryptor(Key, IV), CryptoStreamMode.Write);
        }
    
        public static CryptoStream CreateDecryptionStream(Stream inputStream, byte[] Key, byte[] IV)
        {
            Rijndael rijndael = new RijndaelManaged();
    
            return new CryptoStream(inputStream, rijndael.CreateDecryptor(Key, IV), CryptoStreamMode.Read);
        }
    
        public static void EncryptObjectToFile(object obj, string path, byte[] Key, byte[] IV)
        {
            using FileStream file = new FileStream(path, FileMode.Create);
            using (CryptoStream cryptoStream = CreateEncryptionStream(file, Key, IV))
            {
                WriteObjectToStream(cryptoStream, obj);
            }
        }
    
        public static object DecryptObjectFromFile(string path, byte[] Key, byte[] IV)
        {
            using FileStream file = new FileStream(path, FileMode.Open);
            using (CryptoStream cryptoStream = CreateDecryptionStream(file, Key, IV))
            {
                return ReadObjectFromStream(cryptoStream);
            }
        }
    }
    
    [Serializable]
    public class Student
    {
        public string Name;
        public int Age;
    }
    
    static async Task Main(string[] args)
    {
        // the original string "[This is an example key string!]";
        // I don't know if the length of the string has to be 32, but when I tried 64, it went wrong.
        string cryptoKey = "W1RoaXMgaXMgYW4gZXhhbXBsZSBrZXkgc3RyaW5nIV0=";
        byte[] Key = Convert.FromBase64String(cryptoKey);
        byte[] IV = new byte[16];
        using (RNGCryptoServiceProvider rngcsp = new RNGCryptoServiceProvider())
        {
            rngcsp.GetBytes(IV);
        }
        //same as
        //Rijndael rijndael = new RijndaelManaged();
        //rijndael.GenerateIV();
        //byte[] iv = rijndael.IV;
        List students = new List() { new Student { Name = "John", Age = 10 }, new Student { Name = "Marry", Age = 15 } };
        CryptoSerialization.EncryptObjectToFile(students, Environment.CurrentDirectory + @"\testCrypto.dat", Key, IV);
    
        List newStudents = (List)CryptoSerialization.DecryptObjectFromFile(Environment.CurrentDirectory + @"\testCrypto.dat", Key, IV);
    
        newStudents.ForEach((stu) =>
        {
            Console.WriteLine(stu.Name + ", " + stu.Age);
        });
        Console.ReadKey();
    }
    

提交回复
热议问题