SignAndSeal

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

namespace APress.SignAndSeal
{
    public class NotSerializableException : ApplicationException
    {
        public NotSerializableException() : base() {}
        public NotSerializableException(String message) : base(message) {}
        public NotSerializableException(String message, Exception inner) : base(message, inner) {}
    }

    public abstract class SignedObject
    {
        protected IFormatter m_formatStrategy = null;
        protected byte[] m_signature = null;
        protected byte[] m_wrappedObjectData = null;

        public SignedObject() : base() {}

        public SignedObject(Object ObjectToWrap, IFormatter FormatStrategy)
        {
            int hasSerializableAttrib = (int)ObjectToWrap.GetType().Attributes & (int)TypeAttributes.Serializable;
            
            if(0 == hasSerializableAttrib)
            {
                throw new NotSerializableException("The given object is not serializable.");
            }

            MemoryStream ms = new MemoryStream();
            this.m_formatStrategy = FormatStrategy;
            this.m_formatStrategy.Serialize(ms, ObjectToWrap);
            this.m_wrappedObjectData = ms.GetBuffer();
            ms.Close();
        }

        public SignedObject(Object ObjectToWrap) :
            this(ObjectToWrap, new BinaryFormatter()) {}

        public Object InnerObject
        {
            get
            {
                return(this.m_formatStrategy.Deserialize(
                    new MemoryStream(this.m_wrappedObjectData)));
            }
        }

        public byte[] InnerObjectData
        {
            get
            {
                return(this.m_wrappedObjectData);
            }
        }
    }

    [Serializable]
    public sealed class DSASignedObject : SignedObject, ISerializable
    {
        private DSACryptoServiceProvider m_dsa = null;

        private DSASignedObject(SerializationInfo si, StreamingContext stc)
        {
            this.Initialize();
            this.m_formatStrategy = (IFormatter)Activator.CreateInstance(Type.GetType((String)si.GetValue("FormatterStrategy",
                typeof(System.String))));
            this.m_signature = (byte[])si.GetValue("Signature", typeof(System.Byte[]));
            this.m_wrappedObjectData = (byte[])si.GetValue("ObjectData", typeof(System.Byte[]));
        }

        private DSASignedObject() : base()
        {
            Initialize();
        }

        public DSASignedObject(Object ObjectToWrap, IFormatter FormatStrategy)
            : base(ObjectToWrap, FormatStrategy)
        {
            Initialize();        
        }

        public DSASignedObject(Object ObjectToWrap)
            : base(ObjectToWrap)
        {
            Initialize();        
        }

        private void Initialize()
        {
            m_dsa = new DSACryptoServiceProvider();
        }

        private void Sign()
        {
            this.m_signature = m_dsa.SignData(this.m_wrappedObjectData);
        }

        private bool Verify()
        {
            return m_dsa.VerifyData(this.m_wrappedObjectData, this.m_signature);
        }

        public void GetObjectData(SerializationInfo si, StreamingContext stc)
        {
            si.AddValue("FormatterStrategy", this.m_formatStrategy.GetType().FullName);
            si.AddValue("Signature", this.m_signature);
            si.AddValue("ObjectData", this.m_wrappedObjectData);
        }

        public void Sign(String KeyXMLString)
        {
            m_dsa.FromXmlString(KeyXMLString);
            this.Sign();
        }

        public void Sign(DSAParameters KeyParameters)
        {
            m_dsa.ImportParameters(KeyParameters);
            this.Sign();
        }

        public bool Verify(String KeyXMLString)
        {
            m_dsa.FromXmlString(KeyXMLString);
            return this.Verify();
        }

        public bool Verify(DSAParameters KeyParameters)
        {
            m_dsa.ImportParameters(KeyParameters);
            return this.Verify();
        }
    }


    [Serializable]
    public sealed class RSASignedObject : SignedObject, ISerializable
    {
        private HashAlgorithm m_hash = null;
        private RSACryptoServiceProvider m_rsa = null;

        private RSASignedObject(SerializationInfo si, StreamingContext stc)
        {
            this.Initialize();
            
            String hashAlg = (String)si.GetValue("HashAlgorithm", typeof(System.String));
            
            if("" != hashAlg)
            {
                this.m_hash = (HashAlgorithm)Activator.CreateInstance(Type.GetType(hashAlg));
            }

            this.m_formatStrategy = (IFormatter)Activator.CreateInstance(Type.GetType((String)si.GetValue("FormatterStrategy",
                typeof(System.String))));
            this.m_signature = (byte[])si.GetValue("Signature", typeof(System.Byte[]));
            this.m_wrappedObjectData = (byte[])si.GetValue("ObjectData", typeof(System.Byte[]));
        }

        private RSASignedObject() : base()
        {
            this.Initialize();
        }

        public RSASignedObject(Object ObjectToWrap, IFormatter FormatStrategy)
            : base(ObjectToWrap, FormatStrategy)
        {
            this.Initialize();
        }

        public RSASignedObject(Object ObjectToWrap)
            : base(ObjectToWrap)
        {
            this.Initialize();        
        }

        private void Initialize()
        {
            m_rsa = new RSACryptoServiceProvider();
        }

        private void Sign(HashAlgorithm Hash)
        {
            this.m_signature = m_rsa.SignData(this.m_wrappedObjectData, Hash);
            this.m_hash = Hash;
        }

        private bool Verify()
        {
            return m_rsa.VerifyData(this.m_wrappedObjectData,
                this.m_hash, this.m_signature);
        }

        public void GetObjectData(SerializationInfo si, StreamingContext stc)
        {
            if(null != this.m_hash)
            {
                si.AddValue("HashAlgorithm", this.m_hash.GetType().FullName);
            }
            else
            {
                si.AddValue("HashAlgorithm", "");
            }

            si.AddValue("FormatterStrategy", this.m_formatStrategy.GetType().FullName);
            si.AddValue("Signature", this.m_signature);
            si.AddValue("ObjectData", this.m_wrappedObjectData);
        }

        public void Sign(String KeyXMLString, HashAlgorithm Hash)
        {
            m_rsa.FromXmlString(KeyXMLString);
            this.Sign(Hash);
        }

        public void Sign(RSAParameters KeyParameters, HashAlgorithm Hash)
        {
            m_rsa.ImportParameters(KeyParameters);
            this.Sign(Hash);
        }

        public bool Verify(String KeyXMLString)
        {
            m_rsa.FromXmlString(KeyXMLString);
            return this.Verify();
        }

        public bool Verify(RSAParameters KeyParameters)
        {
            m_rsa.ImportParameters(KeyParameters);
            return this.Verify();
        }
    }

    public abstract class SealedObject
    {
        protected IFormatter m_formatStrategy = null;
        protected byte[] m_wrappedObjectData = null;

        public SealedObject() : base() {}

        public SealedObject(Object ObjectToWrap, IFormatter FormatStrategy)
        {
            int hasSerializableAttrib = (int)ObjectToWrap.GetType().Attributes & (int)TypeAttributes.Serializable;
            
            if(0 == hasSerializableAttrib)
            {
                throw new NotSerializableException("The given object is not serializable.");
            }

            MemoryStream ms = new MemoryStream();
            this.m_formatStrategy = FormatStrategy;
            this.m_formatStrategy.Serialize(ms, ObjectToWrap);
            this.m_wrappedObjectData = ms.GetBuffer();
            ms.Close();
        }

        public SealedObject(Object ObjectToWrap) :
            this(ObjectToWrap, new BinaryFormatter()) {}

        public Object InnerObject
        {
            get
            {
                return(this.m_formatStrategy.Deserialize(
                    new MemoryStream(this.m_wrappedObjectData)));
            }
        }

        public byte[] InnerObjectData
        {
            get
            {
                return(this.m_wrappedObjectData);
            }
        }
    }
    [Serializable]
    public sealed class RSASealedObject : SealedObject, ISerializable
    {
        private RSACryptoServiceProvider m_rsa = null;

        private RSASealedObject(SerializationInfo si, StreamingContext stc)
        {
            this.Initialize();
            this.m_formatStrategy = (IFormatter)Activator.CreateInstance(Type.GetType((String)si.GetValue("FormatterStrategy",
                typeof(System.String))));
            this.m_wrappedObjectData = (byte[])si.GetValue("ObjectData", typeof(System.Byte[]));
        }

        private RSASealedObject() : base()
        {
            Initialize();
        }

        public RSASealedObject(Object ObjectToWrap, IFormatter FormatStrategy)
            : base(ObjectToWrap, FormatStrategy)
        {
            Initialize();        
        }

        public RSASealedObject(Object ObjectToWrap)
            : base(ObjectToWrap)
        {
            Initialize();        
        }

        private void Initialize()
        {
            m_rsa = new RSACryptoServiceProvider();
        }

        public void GetObjectData(SerializationInfo si, StreamingContext stc)
        {
            si.AddValue("FormatterStrategy", this.m_formatStrategy.GetType().FullName);
            si.AddValue("ObjectData", this.m_wrappedObjectData);
        }

        private int MaxDataSize
        {
            get
            {
                if(1024 == m_rsa.KeySize)
                {
                    return(16);
                }
                else
                {
                    return(5);
                }
            }
        }

        private void Encrypt()
        {
            int bytesProcessed = 0;
            int maxDataSize = this.MaxDataSize;
            int newChunkSize = 0;
            byte[] dataChunk = new byte[this.MaxDataSize];
            byte[] encryptedDataChunk = null;
            MemoryStream ms = new MemoryStream();

            do
            {
                newChunkSize = (this.m_wrappedObjectData.Length - bytesProcessed) < maxDataSize ?
                    this.m_wrappedObjectData.Length - bytesProcessed : maxDataSize;
                Array.Copy(this.m_wrappedObjectData, bytesProcessed,
                    dataChunk, 0, newChunkSize);
                encryptedDataChunk = m_rsa.Encrypt(dataChunk, false);
                ms.Write(encryptedDataChunk,
                    0, (int)encryptedDataChunk.Length);
                bytesProcessed += newChunkSize;
            } while (bytesProcessed < this.m_wrappedObjectData.Length);

            ms.Position = 0;

            this.m_wrappedObjectData = new byte[ms.Length];

            Array.Copy(ms.GetBuffer(), 0,
                this.m_wrappedObjectData, 0, (int)ms.Length);
            ms.Close();
        }

        private void Decrypt()
        {
            int bytesProcessed = 0;
            int maxDataSize = this.m_rsa.KeySize / 8;
            int newChunkSize = 0;
            byte[] dataChunk = new byte[this.m_rsa.KeySize / 8];
            byte[] encryptedDataChunk = null;
            MemoryStream ms = new MemoryStream();

            do
            {
                newChunkSize = (this.m_wrappedObjectData.Length - bytesProcessed) < maxDataSize ?
                    this.m_wrappedObjectData.Length - bytesProcessed : maxDataSize;
                Array.Copy(this.m_wrappedObjectData, bytesProcessed,
                    dataChunk, 0, newChunkSize);
                encryptedDataChunk = m_rsa.Decrypt(dataChunk, false);
                ms.Write(encryptedDataChunk,
                    0, (int)encryptedDataChunk.Length);
                bytesProcessed += newChunkSize;
            } while (bytesProcessed < this.m_wrappedObjectData.Length);

            ms.Position = 0;

            this.m_wrappedObjectData = new byte[ms.Length];
            
            Array.Copy(ms.GetBuffer(), 0,
                this.m_wrappedObjectData, 0, (int)ms.Length);
            ms.Close();
        }

        public void Seal(String KeyXMLString)
        {
            m_rsa.FromXmlString(KeyXMLString);
            this.Encrypt();
        }

        public void Seal(RSAParameters KeyParameters)
        {
            m_rsa.ImportParameters(KeyParameters);
            this.Encrypt();
        }

        public void Open(String KeyXMLString)
        {
            m_rsa.FromXmlString(KeyXMLString);
            this.Decrypt();
        }

        public void Open(RSAParameters KeyParameters)
        {
            m_rsa.ImportParameters(KeyParameters);
            this.Decrypt();
        }
    }
}
原文地址:https://www.cnblogs.com/shihao/p/2511960.html