Laden...

XOR - Verschüsselungs Stream (CryptStream)

Erstellt von KainPlan vor 14 Jahren Letzter Beitrag vor 14 Jahren 5.245 Views
K
KainPlan Themenstarter:in
133 Beiträge seit 2009
vor 14 Jahren
XOR - Verschüsselungs Stream (CryptStream)

Beschreibung:

Diese Klasse ist abgeleitet von System.IO.Filestream und überschreibt die Funktionen Read(), Write(), ReadByte() und WriteByte(). In den funktionen wird eine XOR-Verknüpfung mit den Bytes, einem Offset, der Position des Streams und einem Schlüssel verwendet um die Bytes zu verschlüsseln.

Ein Testprojekt habe ich gleich mal mit beigepackt. Ich bitte um Vorschläge zur Verbesserung. 😄


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

namespace System.IO.Cryption
{
    public enum CryptStreamKeyLockAlgorithm
    { None = 0, MD5, SHA1, SHA256, SHA384, SHA512, RIPEMD160 }
    /// <summary>
    /// Provides a generic XOR based cryption stream.
    /// </summary>
    public class CryptStream : FileStream
    {
        public const CryptStreamKeyLockAlgorithm DefaultKeyLockAlgorithm = CryptStreamKeyLockAlgorithm.None;
        public const uint DefaultLoff = 0;

        #region Fields
        private CryptStreamKeyLockAlgorithm alg;
        private byte[] key;
        private uint loff;
        #endregion

        #region Members
        /// <summary>
        /// Gets the generated hash for the key.
        /// </summary>
        public byte[] Key { get { return key; } }
        /// <summary>
        /// Gets the KeyLockAlgorithm for this instance.
        /// </summary>
        public CryptStreamKeyLockAlgorithm KeyLockAlg { get { return alg; } }
        #endregion

        #region Ctor's
        /// <summary>
        /// Creates a new Crypto Stream.
        /// </summary>
        /// <param name="key">Key for the encryption/decryption.</param>
        /// <param name="file">Relative or absolute path to the file.</param>
        /// <param name="fmod">Operation mode.</param>
        public CryptStream(byte[] key, string file, FileMode fmod)
            : base(file, fmod)
        {
            if (key.Length <= 0)
                throw new NotSupportedException("key have to be an byte array with at least one byte of lenght.");

            this.alg = DefaultKeyLockAlgorithm;
            this.key = key;
            this.loff = DefaultLoff;
            init();
        }
        /// <summary>
        /// Creates a new Crypto Stream.
        /// </summary>
        /// <param name="key">Key for the encryption/decryption.</param>
        /// <param name="file">Relative or absolute path to the file.</param>
        /// <param name="fmod">Operation mode.</param>
        public CryptStream(byte[] key, string file, FileMode fmod, CryptStreamKeyLockAlgorithm alg)
            : base(file, fmod)
        {
            if (key.Length <= 0)
                throw new NotSupportedException("key have to be an byte array with at least one byte of lenght.");

            this.alg = alg;
            this.key = key;
            this.loff = DefaultLoff;
            init();
        }
        /// <summary>
        /// Creates a new Crypto Stream.
        /// </summary>
        /// <param name="key">Key for the encryption/decryption.</param>
        /// <param name="file">Relative or absolute path to the file.</param>
        /// <param name="fmod">Operation mode.</param>
        public CryptStream(string key, string file, FileMode fmod)
            : base(file, fmod)
        {
            if (key.Length <= 0)
                throw new NotSupportedException("key have to be an string with at least one char inside.");

            this.alg = DefaultKeyLockAlgorithm;
            this.key = Text.UnicodeEncoding.ASCII.GetBytes(key);
            this.loff = DefaultLoff;
            init();
        }
        /// <summary>
        /// Creates a new Crypto Stream.
        /// </summary>
        /// <param name="key">Key for the encryption/decryption.</param>
        /// <param name="file">Relative or absolute path to the file.</param>
        /// <param name="fmod">Operation mode.</param>
        public CryptStream(string key, string file, FileMode fmod, CryptStreamKeyLockAlgorithm alg)
            : base(file, fmod)
        {
            if (key.Length <= 0)
                throw new NotSupportedException("key have to be an string with at least one char inside.");

            this.alg = alg;
            this.key = Text.UnicodeEncoding.ASCII.GetBytes(key);
            this.loff = DefaultLoff;
            init();
        }
        /// <summary>
        /// Creates a new Crypto Stream.
        /// </summary>
        /// <param name="key">Key for the encryption/decryption.</param>
        /// <param name="file">Relative or absolute path to the file.</param>
        /// <param name="fmod">Operation mode.</param>
        public CryptStream(byte[] key, string file, uint loff,  FileMode fmod)
            : base(file, fmod)
        {
            if (key.Length <= 0)
                throw new NotSupportedException("key have to be an byte array with at least one byte of lenght.");

            this.alg = DefaultKeyLockAlgorithm;
            this.key = key;
            this.loff = loff;
            init();
        }
        /// <summary>
        /// Creates a new Crypto Stream.
        /// </summary>
        /// <param name="key">Key for the encryption/decryption.</param>
        /// <param name="file">Relative or absolute path to the file.</param>
        /// <param name="fmod">Operation mode.</param>
        public CryptStream(byte[] key, string file, uint loff,  FileMode fmod, CryptStreamKeyLockAlgorithm alg)
            : base(file, fmod)
        {
            if (key.Length <= 0)
                throw new NotSupportedException("key have to be an byte array with at least one byte of lenght.");

            this.alg = alg;
            this.key = key;
            this.loff = loff;
            init();
        }
        /// <summary>
        /// Creates a new Crypto Stream.
        /// </summary>
        /// <param name="key">Key for the encryption/decryption.</param>
        /// <param name="file">Relative or absolute path to the file.</param>
        /// <param name="fmod">Operation mode.</param>
        public CryptStream(string key, string file, uint loff,  FileMode fmod)
            : base(file, fmod)
        {
            if (key.Length <= 0)
                throw new NotSupportedException("key have to be an string with at least one char inside.");

            this.alg = DefaultKeyLockAlgorithm;
            this.key = Text.UnicodeEncoding.ASCII.GetBytes(key);
            this.loff = loff;
            init();
        }
        /// <summary>
        /// Creates a new Crypto Stream.
        /// </summary>
        /// <param name="key">Key for the encryption/decryption.</param>
        /// <param name="file">Relative or absolute path to the file.</param>
        /// <param name="fmod">Operation mode.</param>
        public CryptStream(string key, string file, uint loff,  FileMode fmod, CryptStreamKeyLockAlgorithm alg)
            : base(file, fmod)
        {
            if (key.Length <= 0)
                throw new NotSupportedException("key have to be an string with at least one char inside.");

            this.alg = alg;
            this.key = Text.UnicodeEncoding.ASCII.GetBytes(key);
            this.loff = loff;
            init();
        }
        #endregion

        #region Initializing
        private void init()
        {
            MD5 md5;
            SHA1 sha1;
            SHA256 sha256;
            SHA384 sha384;
            SHA512 sha512;
            RIPEMD160 ripemd160;

            switch (alg)
            {

                case CryptStreamKeyLockAlgorithm.MD5:
                    md5 = MD5.Create();
                    key = md5.ComputeHash(key);
                    md5.Clear();
                    break;
                case CryptStreamKeyLockAlgorithm.SHA1:
                    sha1 = SHA1.Create();
                    key = sha1.ComputeHash(key);
                    sha1.Clear();
                    break;
                case CryptStreamKeyLockAlgorithm.SHA256:
                    sha256 = SHA256.Create();
                    key = sha256.ComputeHash(key);
                    sha256.Clear();
                    break;
                case CryptStreamKeyLockAlgorithm.SHA384:
                    sha384 = SHA384.Create();
                    key = sha384.ComputeHash(key);
                    sha384.Clear();
                    break;
                case CryptStreamKeyLockAlgorithm.SHA512:
                    sha512 = SHA512.Create();
                    key = sha512.ComputeHash(key);
                    sha512.Clear();
                    break;
                case CryptStreamKeyLockAlgorithm.RIPEMD160:
                    ripemd160 = RIPEMD160.Create();
                    key = ripemd160.ComputeHash(key);
                    ripemd160.Clear();
                    break;

                default:
                case CryptStreamKeyLockAlgorithm.None:
                    break;

            }
        }
        #endregion

        #region Overrides
        public override int Read(byte[] array, int offset, int count)
        {
            int rc = base.Read(array, offset, count);
            long p = Position - count;

            for (int i = offset; i < rc; i++)
            {
                int idx = (int)(p % key.Length);

                array[i] ^= (byte)(key[idx] ^ (p++ + loff));
            }

            return rc;
        }

        public override void Write(byte[] array, int offset, int count)
        {
            long p = Position;

            for (int i = offset; i < count; i++)
            {
                int idx = (int)(p % key.Length);

                array[i] ^= (byte)(key[idx] ^ (p++ + loff));
            }

            base.Write(array, offset, count);
        }

        public override int ReadByte()
        {
            long p = Position;
            byte b = (byte)base.ReadByte();
            b ^= (byte)(key[p % key.Length] ^ (p + loff));

            return b;
        }

        public override void WriteByte(byte value)
        {
            long p = Position;
            byte b = value;
            b ^= (byte)(key[p % key.Length] ^ (p + loff));

            base.WriteByte(b);
        }
        #endregion
    }
}

Schlagwörter: Verschlüsselung, Encryption, Decryption, XOR

1.002 Beiträge seit 2007
vor 14 Jahren

Hallo KainPlan,

du könntest die englischen Formulierungen in den Exceptions nochmal überarbeiten, die sind etwas ... wirr 😉.

m0rius

Mein Blog: blog.mariusschulz.com
Hochwertige Malerarbeiten in Magdeburg und Umgebung: M'Decor, Ihr Maler für Magdeburg

I
279 Beiträge seit 2008
vor 14 Jahren

Vllt. gleich die CryptoStream Klasse verwenden ^^

K
KainPlan Themenstarter:in
133 Beiträge seit 2009
vor 14 Jahren

du könntest die englischen Formulierungen in den Exceptions nochmal überarbeiten, die sind etwas ... wirr 😉.

Ja definitiv, sollte nicht beim Programmieren Saufen bzw. nach dem Saufen Programmieren... ^^