субота, 11. новембар 2017.

Kriptografija, heširanje i potpisivanje podataka - 1 deo

Zaštita podataka i aplikacija je izuzetno kompleksna i opširna stvar i na tu temu bi se mogle napisati mnogobrojne knjige. Iz tog razloga ograničiću se na kriptografiju, heširanje i eventualno na digitalno potpisivanje u čak 3 posta ili 3 dela u kojima ću vam predstaviti čak 29 primera programerskog code-a u C# programskom jeziku kako bi ste se što bolje upoznali sa klasama .NetFramework-a koje na najjednostavniji način obavljaju najkompleksniju enkripciju i dekripciju. Svi primeri su bazirani prema Microsoft primerima sa malo promene, tek toliko da bi se promene uklopile u verziju C# 7.0 bez gubljenja ni jedne linije koda stručnosti. Poznavajući rad sa klasama i metodama System.Security imenskog prostora sami će te u budućnosti lako birati i kombinovati vaš vlastiti način zaštite vaših lozinki, skrivenih poruka, određenih podataka i aplikacija. Opet imajte u vidu da mi nije namera da vas učim hacker-skim veštinama već zaštiti. Za zloupotrebu pre svega programerske inteligencije, pa tek onda hacker-skih veština ste sami odgovorni. Bolje vam je da se usmerite što pre ka vlastitoj kreativnosti i da uspete u životu, nego da vas vaše znanje i talenti koštaju više nego što možete i pretpostaviti.


( Enigma - Nemačka mašina za šifrovanje radio telegrafskih poruka )

Kriptografija je reč grčkog porekla koja znači tajnopis. To je nauka koja se bavi metodama očuvanja tajnosti informacija. Šifre i digitalni potpisi su kriptografske tehnike koje se koriste da bi se implementirali bezbednosni servisi. Enkripcija vam je samo drugi naziv za šifrovanje podataka dok je deskripcija, koju češće zovemo dekripcija dešifrovanje podataka. Prva kriptografija vam se koristila čak u  vreme Julija Cezara i on se smatra prvim vojskovođom koji je koristio kriptografiju u svojim bitkama. Jednostavno je koristio abecedu i sva slova pomerao za par mesta i na taj način ih šifrovao. Njegove poruke su mogli da dešifruju samo oni koji su poznavali “pomeri za“ pravilo. Još pre računara postojalo je mnoštvo tehnika za šifrovanje poput “vižnerova šifra“, “playafairova šifra“ itd. Danas zahvaljujući računarima, ali i kriptografskoj podršci kroz .NetFramework klase, vama je omogućeno da bezbedno razmenjujete važne ključeve, sprečavate prisluškivanje, otkrivate izmene u porukama, generišete jednosmerne heševe za čuvanje lozinki i pravite digitalne potpise.

Kako da enkriptujete i dekriptujete podatke koristeći Aes klasu?

AES – Advanced Encryption Standard spada u simetričnu enkripciju. To znači da jedan isti ključ služi i za enkriptovanje i za dekriptovanje podataka. U .NetFramework-u postoje 4 simetrična algoritma od kojih se Rijandel – Rajndal ili Rejndon algoritam smatra najjačim. On je brz i bezbedan i za njega postoje dve njegove implementacije. Klasa Rijandel i Aes klasa. Klasa Aes je uvedena .Net Framework-om 3.5 i jedina njena razlika od klase Rijandel je u tome što Aes klasa ne dozvoljava da smanjujete jačinu šifre menjanjem veličine bloka. Ja vam definitivno preporučujem da koristite Aes klasu. Obe klase omogućavaju upotrebu simetričnih ključeva dužine 16, 24 ili 32 bajta. Klasa Aes je apstraktna bazna klasa koja nasleđuje klasu SymmetricAlgorithm i svu njenu simetričnu implementaciju. Pogledajte primer koji na najjednostavniji način demonstrira upotrebu Aes klase:

using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Cryptography;

namespace AesCryptography
{
    class Program
    {
        static void Main(string[] args)
        {
            Protection protection = new Protection();

            try
            {
                using (Aes aes = Aes.Create())
                {
                    Write("Enter some text you want encrypt: ");
                    string text = ReadLine();

                    // Encrypt the string to an array of bytes
                    byte[] encrypted = protection.Encrypt(text, aes.Key, aes.IV);
                    string eText = String.Empty;

                    foreach (var b in encrypted)
                    {
                        eText += b.ToString() + ", ";

                    }

                    WriteLine(Environment.NewLine + $"Encrypted text: {eText}");

                    // Decrypt the bytes to a string
                    string decrypted = protection.Decrypt(encrypted, aes.Key, aes.IV);
                    WriteLine(Environment.NewLine + $"Decrypted text: {decrypted}");

                }
            }
            catch (Exception e)
            {
                WriteLine(Environment.NewLine + $"Error: {e.Message}");
               
            }

            WriteLine(Environment.NewLine + "Press any key to continue...");
            ReadKey();

        }
    }

    class Protection
    {
        public byte[] Encrypt(string Text, byte[] Key, byte[] IV)
        {
            // Check values
            if (Text == null || Text.Length <= 0) throw new ArgumentNullException("Text");
            if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV");

            byte[] eData;

            // Create an Aes object with the specified Key and IV
            using (Aes aes = Aes.Create())
            {
                aes.Key = Key;
                aes.IV = IV;

                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(aes.Key, aes.IV), CryptoStreamMode.Write))
                    {
                        using (StreamWriter sw = new StreamWriter(cs))
                        {
                            // Write the data to the stream
                            sw.Write(Text);

                        }

                        eData = ms.ToArray();

                    }
                }
            }

            // Returned the encrypted bytes from the memory stream
            return eData;

        }

        public string Decrypt(byte[] cText, byte[] Key, byte[] IV)
        {
            // Check values
            if (cText == null || cText.Length <= 0) throw new ArgumentNullException("cText");
            if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV");

            string dData;

            using (Aes aes = Aes.Create())
            {
                aes.Key = Key;
                aes.IV = IV;

                using (MemoryStream ms = new MemoryStream(cText))
                {
                    using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(aes.Key, aes.IV), CryptoStreamMode.Read))
                    {
                        using (StreamReader sr = new StreamReader(cs))
                        {
                            // Read the decrypted bytes and place them in a string
                            dData = sr.ReadToEnd();

                        }
                    }
                }
            }

            // Returned the decrypted string
            return dData;

        }
    }
}

Kada pokrenete navedeni program dobićete sličan rezultat ali ne i identičan. Svaki put kad pokrenete program i unesete isti tekst za enkriptovanje, dobićete drugačiji niz enkriptovanih byte podataka.

Enter some text you want encrypt: My name is Manuel Radovanovic. My blog is at www.manuelradovanovic.com

Encrypted text: 200, 32, 147, 214, 73, 80, 207, 191, 161, 184, 3, 141, 106, 197, 111, 185, 9, 142, 195, 60, 72, 52, 147, 79, 232, 56, 190, 33, 73, 204, 33, 44, 5, 66, 251, 57, 118, 142, 20, 58, 82, 68, 4, 36, 158, 28, 197, 70, 185, 79, 55, 28, 245, 181, 4, 3, 254, 154, 80, 124, 78, 155, 193, 49, 12, 208, 113, 247, 104, 246, 61, 96, 137, 192, 224, 132, 91, 66, 201, 124,

Decrypted text: My name is Manuel Radovanovic. My blog is at www.manuelradovanovic.com

Press any key to continue...

Kako to sve izgleda možete pogledati i na video-u:


( C# 6.0 Tutorial - Advanced - 52. Aes Cryptography, Encrypt and Decrypt Example )

Kako da enkriptujete i dekriptujete podatke koristeći AesCryptoServiceProvider klasu?

Prethodni code ništa nije drugačiji od sledećeg, osim što se umesto Aes klase koristi klasa AesCryptoServiceProvider čiji je algoritam implementiran od operativnog sistema. Pogledajte primer gde se koristi simetrična enkripcija i dekripcija koja koristi CAPI – Cryptograhic Application Programming Interfaces i implementira AES – Advanced Encryption Standard algoritam:

using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Cryptography;

namespace AesCryptoServiceProviderCryptography
{
    class Program
    {
        static void Main(string[] args)
        {
            Protection protection = new Protection();

            try
            {
                using (AesCryptoServiceProvider acsp = new AesCryptoServiceProvider())
                {
                    Write("Enter some text you want to encrypt: ");
                    string text = ReadLine();

                    // Encrypt the string to an array of bytes
                    byte[] encrypted = protection.Encrypt(text, acsp.Key, acsp.IV);

                    string eText = String.Empty;

                    foreach (var b in encrypted)
                    {
                        eText += b.ToString() + ", ";

                    }

                    WriteLine(Environment.NewLine + $"Encrypted text: {eText}");

                    // Decrypt the bytes to a string
                    string decrypted = protection.Decrypt(encrypted, acsp.Key, acsp.IV);
                    WriteLine(Environment.NewLine + $"Decrypted text: {decrypted}");

                }
            }
            catch (Exception e)
            {
                WriteLine(Environment.NewLine + $"Error: {e.Message}");
               
            }

            WriteLine(Environment.NewLine + "Press any key to continue...");
            ReadKey();

        }
    }

    class Protection
    {
        public byte[] Encrypt(string Text, byte[] Key, byte[] IV)
        {
            // Check values
            if (Text == null || Text.Length <= 0) throw new ArgumentNullException("Text");
            if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV");

            byte[] eData;

            // Create a new instance of the AesCryptoServiceProvider class
            // This generates a new Key and IV initalization vector
            using (AesCryptoServiceProvider acsp = new AesCryptoServiceProvider())
            {
                acsp.Key = Key;
                acsp.IV = IV;

                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, acsp.CreateEncryptor(acsp.Key, acsp.IV), CryptoStreamMode.Write))
                    {
                        using (StreamWriter sw = new StreamWriter(cs))
                        {
                            // Write data to the stream
                            sw.Write(Text);

                        }

                        eData = ms.ToArray();
                    }
                }
            }

            // Returned the encrypted bytes from the memory stream
            return eData;

        }

        public string Decrypt(byte[] cText, byte[] Key, byte[] IV)
        {
            // Check values
            if (cText == null || cText.Length <= 0) throw new ArgumentNullException("cText");
            if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV");

            string dData;

            // Create an AesCryptoServiceProvider object with the specified Key and IV
            using (AesCryptoServiceProvider acsp = new AesCryptoServiceProvider())
            {
                acsp.Key = Key;
                acsp.IV = IV;

                using (MemoryStream ms = new MemoryStream(cText))
                {
                    using (CryptoStream cs = new CryptoStream(ms, acsp.CreateDecryptor(acsp.Key, acsp.IV), CryptoStreamMode.Read))
                    {
                        using (StreamReader sr = new StreamReader(cs))
                        {
                            // Read the decrypted bytes and place them in a string
                            dData = sr.ReadToEnd();

                        }
                    }
                }
            }

            // Returned the decrypted string
            return dData;

        }
    }
}

Kada pokrenete navedeni program dobićete sličan rezultat ali ne i identičan. Svaki put kad pokrenete program i unesete isti tekst za enkriptovanje, dobićete drugačiji niz enkriptovanih byte podataka.

Enter some text you want to encrypt: My name is Manuel Radovanovic. Visit my blog at www.manuelradovanovic.com

Encrypted text: 162, 141, 234, 105, 226, 28, 44, 200, 90, 254, 146, 143, 8, 225, 205, 134, 115, 67, 59, 109, 143, 115, 159, 188, 66, 195, 147, 115, 60, 109, 214, 203, 17, 244, 90, 44, 92, 233, 41, 179, 19, 37, 210, 73, 173, 212, 36, 231, 170, 40, 39, 155, 120, 91, 77, 49, 88, 138, 93, 202, 38, 100, 18, 157, 15, 230, 239, 250, 21, 102, 152, 228, 194, 88, 82, 128, 5, 88, 227, 214,

Decrypted text: My name is Manuel Radovanovic. Visit my blog at www.manuelradovanovic.com

Press any key to continue...

Kako to sve izgleda možete pogledati i na video-u:


( C# 6.0 Tutorial - Advanced - 53. AesCryptoServiceProvider Cryptography, Encrypt and Decrypt Example )

Kako da enkriptujete i dekriptujete podatke koristeći AesManaged klasu?


Već smo naveli da Aes klasa ne koristi menjanje veličine bloka. Međutim, vi možete koristiti klasu AesManaged koja obezbeđuje upravljanu implementaciju AES – Advanced Encryption Standard-a, simetričnog algoritma koji je zasnovan na Rijndael-u. Na taj način vi vršite enkripciju na isti način kao klasa Rijandael stime što vam je veličina bloka limitirana, fiksna i to na 128 bita i ne dozvoljava povratni režim. Sledeći code je identičan prethodnom, samo što koristi klasu AesManaged klasu i stime bolje šifrovanje:

using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Cryptography;

namespace AesManagedExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Protection protection = new Protection();

            try
            {
                using (AesManaged am = new AesManaged())
                {
                    Write("Enter some text you want to encrypt: ");
                    string text = ReadLine();

                    // Encrypt the string to an array of bytes
                    byte[] encrypted = protection.Encrypt(text, am.Key, am.IV);

                    string eText = String.Empty;

                    foreach (var b in encrypted)
                    {
                        eText += b.ToString() + ", ";

                    }

                    WriteLine(Environment.NewLine + $"Encrypted text: {eText}");

                    // Decrypt the bytes to a string
                    string decrypted = protection.Decrypt(encrypted, am.Key, am.IV);
                    WriteLine(Environment.NewLine + $"Decrypted text: {decrypted}");

                }
            }
            catch (Exception e)
            {
                WriteLine(Environment.NewLine + $"Error: {e.Message}");
               
            }

            WriteLine(Environment.NewLine + "Press any key to continue...");
            ReadKey();

        }
    }

    class Protection
    {
        public byte[] Encrypt(string Text, byte[] Key, byte[] IV)
        {
            // Check values
            if (Text == null || Text.Length <= 0) throw new ArgumentNullException("Text");
            if (Key == null || Text.Length <= 0) throw new ArgumentNullException("Key");
            if (IV == null || Text.Length <= 0) throw new ArgumentNullException("IV");

            byte[] eData;

            // Create a new instance of the AesManaged class
            // This generates a new Key and IV initalization vector
            using (AesManaged am = new AesManaged())
            {
                am.Key = Key;
                am.IV = IV;

                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, am.CreateEncryptor(am.Key, am.IV), CryptoStreamMode.Write))
                    {
                        using (StreamWriter sw = new StreamWriter(cs))
                        {
                            // Write data to the stream
                            sw.Write(Text);

                        }

                        eData = ms.ToArray();

                    }
                }
            }

            // Return the encrypted bytes from the memory stream
            return eData;

        }

        public string Decrypt(byte[] cText, byte[] Key, byte[] IV)
        {
            // Check values
            if (cText == null || cText.Length <= 0) throw new ArgumentNullException("cText");
            if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV");

            string dData;

            // Create an AesManaged object with the specified Key and IV
            using (AesManaged am = new AesManaged())
            {
                am.Key = Key;
                am.IV = IV;

                using (MemoryStream ms = new MemoryStream(cText))
                {
                    using (CryptoStream cs = new CryptoStream(ms, am.CreateDecryptor(am.Key, am.IV), CryptoStreamMode.Read))
                    {
                        using (StreamReader sr = new StreamReader(cs))
                        {
                            // Read the descrypted bytes and place them in a string
                            dData = sr.ReadToEnd();

                        }
                    }
                }
            }

            // Returned the decrypted string
            return dData;

        }
    }
}

Kada pokrenete navedeni program dobićete sličan rezultat ali ne i identičan. Svaki put kad pokrenete program i unesete isti tekst za enkriptovanje, dobićete drugačiji niz enkriptovanih byte podataka.

Enter some text you want to encrypt: Manuel Radovanovic www.manuelradovanovic.com

Encrypted text: 48, 87, 176, 84, 24, 186, 241, 61, 231, 19, 124, 253, 65, 237, 168, 100, 92, 169, 117, 155, 161, 150, 15, 98, 11, 106, 39, 205, 59, 49, 57, 98, 217, 80, 154, 29, 157, 51, 108, 75, 20, 10, 144, 246, 199, 183, 223, 122,

Decrypted text: Manuel Radovanovic www.manuelradovanovic.com

Press any key to continue...

Kako to sve izgleda možete pogledati i na video-u:


( C# 6.0 Tutorial - Advanced - 54. AesManaged Cryptography, Encrypt and Decrypt Example )

Kako da enkriptujete i dekriptujete podatke koristeći CryptoAPITransform klasu?

Prethodni primeri su odlični ali postoje i drugi načini da enkriptujete i dekriptujete vaše podatke. Npr. šta ako vi samo želite da izvršite jednostavnu kriptografsku transformaciju podataka? Tada možete da koristite klasu CryptoAPITransform. Ova klasa se ne može naslediti. Pogledajte sledeći primer koji demonstrira kako da koristite članove CryptoAPITransfrorm klase. Obratite pažnju kako će vam sad izgledati enkriptovani podaci:

using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;
using System.Security.Cryptography;

namespace CryptoAPITransformExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Protection protection = new Protection();

            try
            {
                    Write("Enter some text you want to encrypt: ");
                    string text = ReadLine();

                    byte[] sourceBytes = Encoding.ASCII.GetBytes(text);

                    byte[] encrypted = protection.Encrypt(sourceBytes);
                    WriteLine(Environment.NewLine + $"Encrypted text: {Encoding.ASCII.GetString(encrypted)}");

                    byte[] decrypted = protection.Decrypt(encrypted);
                    WriteLine(Environment.NewLine + $"Decrypted text: {Encoding.ASCII.GetString(decrypted)}");

               
            }
            catch (Exception e)
            {
                WriteLine(Environment.NewLine + $"Error: {e.Message}");
               
            }

            WriteLine(Environment.NewLine + "Press any key to continue...");
            ReadKey();
           
        }
    }

    class Protection
    {
        // Use a public service provider for encryption and decrypton
        static DESCryptoServiceProvider dcsp = new DESCryptoServiceProvider();

        public byte[] Encrypt(byte[] sourceBytes)
        {
            int currentPosition = 0;
            byte[] targetBytes = new byte[1024];
            int sourceByteLength = sourceBytes.Length;

            // Crypto a DES encryptor from this instance to perform encryption
            CryptoAPITransform caTransform = (CryptoAPITransform)dcsp.CreateEncryptor();

            // Retreive the block size to read the bytes
            int inputBlockSize = caTransform.InputBlockSize;

            // Retreive the key handle
            IntPtr keyHandle = caTransform.KeyHandle;

            // Retreive the block size to write the bytes
            int outputBlockSize = caTransform.OutputBlockSize;

            // Determine if multiple blocks can be transformed
            if (caTransform.CanTransformMultipleBlocks)
            {
                int numBytesRead = 0;
                while (sourceByteLength - currentPosition >= inputBlockSize)
                {
                    // Transform the bytes from currentPosition in the sourceBytes array,
                    // writing the bytes to the targetBytes array
                    numBytesRead = caTransform.TransformBlock(sourceBytes, currentPosition, inputBlockSize, targetBytes, currentPosition);

                    // Advance the current position in the sourceBytes array
                    currentPosition += numBytesRead;

                }

                // Transform the final block of bytes
                byte[] finalBytes = caTransform.TransformFinalBlock(sourceBytes, currentPosition, sourceByteLength - currentPosition);

                // Copy the contents of the finalBytes array to the targetBytes array
                finalBytes.CopyTo(targetBytes, currentPosition);

            }

            // Determine if the current transform can be reused
            if (!caTransform.CanReuseTransform)
            {
                // Free up any used resourced
                caTransform.Clear();

            }

            // Trim the extra bytes in the array that were not used
            return TrimArray(targetBytes);

        }

        public byte[] Decrypt(byte[] sourceBytes)
        {
            byte[] targetBytes = new byte[1024];
            int currentPosition = 0;

            // Create a DES decryptor from this instance to perform decryption
            CryptoAPITransform caTransform = (CryptoAPITransform)dcsp.CreateDecryptor();

            int inputBlockSize = caTransform.InputBlockSize;
            int sourceByteLength = sourceBytes.Length;

            int numBytesRead = 0;
            while (sourceByteLength - currentPosition >= inputBlockSize)
            {
                // Transform the bytes from current position in the sourceBytes array,
                // writing the bytes to the targetBytes array
                numBytesRead = caTransform.TransformBlock(sourceBytes, currentPosition, inputBlockSize, targetBytes, currentPosition);

                // Advance the current position in the source array
                currentPosition += numBytesRead;

            }

            // Transform the final block of bytes
            byte[] finalBytes = caTransform.TransformFinalBlock(sourceBytes, currentPosition, sourceByteLength - currentPosition);

            // Copy the contents of the finalBytes array to the targetBytes array
            finalBytes.CopyTo(targetBytes, currentPosition);

            // Strip out the second block of bytes
            Array.Copy(targetBytes, (inputBlockSize * 2), targetBytes, inputBlockSize, targetBytes.Length - (inputBlockSize * 2));

            // Trim the extra bytes in the array that were not used
            return TrimArray(targetBytes);

        }
       
        private static byte[] TrimArray(byte[] targetArray)
        {
            IEnumerator enum1 = targetArray.GetEnumerator();
            int i = 0;

            while (enum1.MoveNext())
            {
                if (enum1.Current.ToString().Equals("0"))
                {
                    break;

                }

                i++;

            }

            // Create a new array with the number of valid bytes
            byte[] returnedArray = new byte[i];
            for (int j = 0; j < i; j++)
            {
                returnedArray[j] = targetArray[j];

            }

            return returnedArray;

        }
    }
}

Kada pokrenete navedeni program dobićete sličan rezultat ali ne i identičan. Svaki put kad pokrenete program i unesete isti tekst za enkriptovanje, dobićete drugačiji niz enkriptovanih byte podataka.

Enter some text you want to encrypt: Manuel Radovanovic

Encrypted text: ??\eU?0????"9g[????]

Decrypted text: Manuel Radovanovic

Press any key to continue...

Kako to sve izgleda možete pogledati i na video-u:




( C# 6.0 Tutorial - Advanced - 55. CryptoAPITransform Cryptography, Encrypt and Decrypt Example )

Kako da enkriptujete i dekriptujete podatke koristeći RijndaelManaged klasu?

Bolje je da koristite Aes klasu nego RijandaelManaged jer se ona pre svega smatra prethodnicom Aes klase. Ali za razliku od Aes klase, u ovom slučaju možete koristiti algoritam dužine ključa 128, 192 ili 256 bita. Takođe podržava blok veličine 128, 192 ili 256 bita. Pogledajte primer koji se ne razlikuje mnogo od primera Aes klase, ali koristi RijandaelManaged klasu:

using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Cryptography;

namespace RijndealManagedCryptographyExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Protection protection = new Protection();

            try
            {
                using (Rijndael r = Rijndael.Create())
                {
                    Write("Enter some text you want to encrypt: ");
                    string text = ReadLine();

                    // Encrypt the string to an array of bytes
                    byte[] encrypted = protection.Encrypt(text, r.Key, r.IV);

                    string eText = String.Empty;

                    foreach (var b in encrypted)
                    {
                        eText += b.ToString() + ", ";

                    }

                    WriteLine(Environment.NewLine + $"Encrypted text: {eText}");

                    // Decrypted the bytes to a string
                    string decrypted = protection.Decrypt(encrypted, r.Key, r.IV);
                    WriteLine(Environment.NewLine + $"Decrypted text: {decrypted}");

                }
            }
            catch (Exception e)
            {
                WriteLine(Environment.NewLine + $"Error: {e.Message}");
               
            }

            WriteLine(Environment.NewLine + "Press any key to continue...");
            ReadKey();

        }
    }

    class Protection
    {
        public byte[] Encrypt(string Text, byte[] Key, byte[] IV)
        {
            // Check values
            if (Text == null || Text.Length <= 0) throw new ArgumentNullException("Text");
            if (Key == null || Text.Length <= 0) throw new ArgumentNullException("Key");
            if (IV == null || Text.Length <= 0) throw new ArgumentNullException("IV");

            byte[] eData;

            // Create a new instance of the Rijendael class
            // This generates a new Key and IV initalization vector
            using (Rijndael r = Rijndael.Create())
            {
                r.Key = Key;
                r.IV = IV;

                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, r.CreateEncryptor(r.Key, r.IV), CryptoStreamMode.Write))
                    {
                        using (StreamWriter sw = new StreamWriter(cs))
                        {
                            // Write data to the stream
                            sw.Write(Text);

                        }

                        eData = ms.ToArray();

                    }
                }
            }

            // Returned the encrypted bytes from the memory stream
            return eData;

        }

        public string Decrypt(byte[] cText, byte[] Key, byte[] IV)
        {
            // Check values
            if (cText == null || cText.Length <= 0) throw new ArgumentNullException("cText");
            if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV");

            string dData;

            // Create a Rijandel object with the specified Key and IV
            using (Rijndael r = Rijndael.Create())
            {
                r.Key = Key;
                r.IV = IV;

                using (MemoryStream ms = new MemoryStream(cText))
                {
                    using (CryptoStream cs = new CryptoStream(ms, r.CreateDecryptor(r.Key, r.IV), CryptoStreamMode.Read))
                    {
                        using (StreamReader sr = new StreamReader(cs))
                        {
                            // Read the descrypted bytes and place them in a string
                            dData = sr.ReadToEnd();

                        }
                    }
                }
            }

            // Returned the decrypted string
            return dData;

        }
    }
}

Kada pokrenete navedeni program dobićete sličan rezultat ali ne i identičan. Svaki put kad pokrenete program i unesete isti tekst za enkriptovanje, dobićete drugačiji niz enkriptovanih byte podataka.

Enter some text you want to encrypt: Manuel Radovanovic www.manuelradovanovic.com

Encrypted text: 137, 123, 44, 146, 173, 234, 67, 160, 72, 147, 41, 201, 133, 1, 73, 144, 92, 126, 100, 35, 46, 138, 59, 220, 50, 55, 24, 253, 51, 33, 66, 187, 225, 198, 150, 129, 81, 145, 170, 131, 255, 132, 20, 213, 112, 252, 139, 186,

Decrypted text: Manuel Radovanovic www.manuelradovanovic.com

Press any key to continue...

Kako to sve izgleda možete pogledati i na video-u:


( C# 6.0 Tutorial - Advanced - 56. RijndaelManaged Cryptography, Encrypt and Decrypt Example )

Kako da izvršite zaštitu podataka metodom Protect koristeći DataProtectionScope enumeraciju?

Do sada ste se u navedenim primerima oslanjali na klase. Ovaj primer za zaštitu podataka koristi enumeraciju koja u sebi sadrži dve metode. Protect i Unprotect. Ukoliko hoćete da koristite ove metode, morate napraviti referencu na System.Security.dll. Pogledajte u sledećem primeru kako možete zaštiti neki niz podataka:

using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;

namespace DataProtectionScopeEnumeratorExample
{
    class Program
    {
        // First, you need add the reference System.Security.dll
        // Create byte array for additional entropy when using Protect method
        static byte[] aditionalEntropy = { 5, 6, 7, 8, 9 };

        static void Main(string[] args)
        {
            Protection protection = new Protection();

            byte[] password = new byte[8];
            WriteLine("Enter the numbers 0-9:");
            for (byte i = 0; i < password.Length; i++)
            {
                Write($"Number - {i + 1} of {password.Length} = ");
                password[i] = byte.Parse(ReadLine());

            }

            // Encrypt the data
            byte[] encrypted = protection.Protect(password);
            WriteLine(Environment.NewLine + "The encrypted byte array is:" + Environment.NewLine);
            Print(encrypted);

            // Decrypt the data and store in a byte array
            byte[] originalData = protection.Unprotect(encrypted);
            WriteLine(Environment.NewLine + "The original data is: " + Environment.NewLine);
            Print(originalData);

            // c# 7.0 Local function
            void Print (byte[] array)
            {
                foreach (byte b in array)
                {
                    Write($"\t {b}");

                }

                WriteLine();
            }

            WriteLine(Environment.NewLine + "Press any key to continue...");
            ReadKey();

        }

        class Protection
        {
            public byte[] Protect(byte[] data)
            {
                try
                {
                    // Encrypt the data using DataProtectionScope.Currentuser
                    // The result can be decrypted only by the same current user
                    return ProtectedData.Protect(data, aditionalEntropy, DataProtectionScope.CurrentUser);
                }
                catch (CryptographicException ex)
                {
                    WriteLine(Environment.NewLine + "Data was not encrypted. An error occured.");
                    WriteLine(ex.Message);
                    return null;
                }
            }

            public byte[] Unprotect(byte[] data)
            {
                try
                {
                    // Decrypt the data using DataProtectionScope.CurrentUser
                    return ProtectedData.Unprotect(data, aditionalEntropy, DataProtectionScope.CurrentUser);

                }
                catch (CryptographicException ex)
                {
                    WriteLine(Environment.NewLine + "Data was not decrypted. An error occured.");
                    WriteLine(ex.Message);
                    return null;

                }
            }
        }
    }
}

Kada pokrenete navedeni program dobićete sličan rezultat ali ne i identičan. Svaki put kad pokrenete program i unesete isti tekst za enkriptovanje, dobićete drugačiji niz enkriptovanih byte podataka.

Enter the numbers 0-9:

Number - 1 of 8 = 1
Number - 2 of 8 = 2
Number - 3 of 8 = 3
Number - 4 of 8 = 4
Number - 5 of 8 = 5
Number - 6 of 8 = 6
Number - 7 of 8 = 7
Number - 8 of 8 = 8

The encrypted byte array is:

         1       0       0       0       208     140     157     223     1       21      209     17      140     122
 0       192     79      194     151     235     1       0       0       0       95      212     120     100     67
 194     241     66      178     17      77      199     16      138     199     88      0       0       0       0
 2       0       0       0       0       0       16      102     0       0       0       1       0       0       32
 0       0       0       104     205     180     89      43      117     72      165     125     149     25      188
 181     159     26      153     171     172     125     8       224     116     166     90      210     35      174
 202     129     215     50      129     0       0       0       0       14      128     0       0       0       2
 0       0       32      0       0       0       34      80      33      237     83      115     246     71      49
 15      116     137     65      0       153     80      190     231     151     130     61      56      185     251
 98      253     41      160     245     232     91      120     16      0       0       0       49      112     220
 10      242     87      192     25      207     3       43      69      69      230     100     7       64      0
 0       0       131     120     125     74      119     18      204     171     197     60      21      71      14
 11      138     152     9       89      8       39      196     243     22      54      35      31      18      47
 160     74      63      109     162     153     74      9       146     11      85      85      33      177     161
 43      62      212     143     51      221     14      146     113     181     42      102     175     131     184
 14      16      211     128     209     28

The original data is:

         1       2       3       4       5       6       7       8

Press any key to continue...

Kako to sve izgleda možete pogledati i na video-u:


( C# 6.0 Tutorial - Advanced - 57. How to use DataProtectionScope Cryptography with CurrentUser )

Kako da enkriptujete i dekriptujete podatke koristeći TripleDESCryptoServiceProvider klasu?

Za sledeći primer ćemo izabrati opet neobičnu tehniku kriptovanja i dekriptovanja podataka. Ja vam preporučujem da koristite AesServiceProvider klasu umesto ove, dok ovu tehniku možete koristiti čisto radi kompatabilnosti sa starijim aplikacijama i podacima. Ova klasa definiše objekat da bi pristupila TripleDES verziji algoritma za CSP - provajder kriptografskih usluga. Ovaj algoritam podržava dužinu ključa od 128 do 192 bita u koracima od 64 bita. Klasa se ne može naslediti. Pogledajte jednostavan primer kako se koristi:

using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Cryptography;

namespace TripleCryptoServiceProviderExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Protection protection = new Protection();

            try
            {
                using (TripleDESCryptoServiceProvider tDESCsp = new TripleDESCryptoServiceProvider())
                {
                    Write("Enter some text you want to encrypt: ");
                    string text = ReadLine();

                    // Encrypt the string to an array of bytes
                    byte[] encrypted = protection.Encrypt(text, tDESCsp.Key, tDESCsp.IV);
                    string eText = String.Empty;

                    foreach (var b in encrypted)
                    {
                        eText += b.ToString() + ", ";

                    }

                    WriteLine(Environment.NewLine + $"Encrypted text: {eText}");

                    // Decrypt the bytes to a string
                    string decrypted = protection.Decrypt(encrypted, tDESCsp.Key, tDESCsp.IV);
                    WriteLine(Environment.NewLine + $"Decrypted text: {decrypted}");

                }
            }
            catch (Exception ex)
            {
                WriteLine(Environment.NewLine + $"Error: {ex.Message}");
              
            }

            WriteLine(Environment.NewLine + "Press any key to continue...");
            ReadKey();

        }    
    }

    class Protection
    {
        public byte[] Encrypt(string Text, byte[] Key, byte[] IV)
        {
            // Check values
            if (Text == null || Text.Length <= 0) throw new ArgumentNullException("Text");
            if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV");

            byte[] eData;

            // Create a TripleDESCryptoServiceProvider object with the specified Key and IV
            using (TripleDESCryptoServiceProvider tDESCsp = new TripleDESCryptoServiceProvider())
            {
                tDESCsp.Key = Key;
                tDESCsp.IV = IV;

                using (MemoryStream ms = new MemoryStream())
                {
                    using (CryptoStream cs = new CryptoStream(ms, tDESCsp.CreateEncryptor(tDESCsp.Key, tDESCsp.IV), CryptoStreamMode.Write))
                    {
                        using (StreamWriter sw = new StreamWriter(cs))
                        {
                            // Write the data to the stream
                            sw.Write(Text);

                        }

                        eData = ms.ToArray();

                    }
                }
            }

            // Returned the encrypted bytes from the memory stream
            return eData;

        }

        public string Decrypt(byte[] cText, byte[] Key, byte[] IV)
        {
            // Check values
            if (cText == null || cText.Length <= 0) throw new ArgumentNullException("cText");
            if (Key == null || Key.Length <= 0) throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0) throw new ArgumentNullException("IV");

            string dData;

            using (TripleDESCryptoServiceProvider tDESCsp = new TripleDESCryptoServiceProvider())
            {
                tDESCsp.Key = Key;
                tDESCsp.IV = IV;

                using (MemoryStream ms = new MemoryStream(cText))
                {
                    using (CryptoStream cs = new CryptoStream(ms, tDESCsp.CreateDecryptor(tDESCsp.Key, tDESCsp.IV), CryptoStreamMode.Read))
                    {
                        using (StreamReader sr = new StreamReader(cs))
                        {
                            // Read the decrypted bytes and place them in a string
                            dData = sr.ReadToEnd();

                        }
                    }
                }
            }

            // Returned the decrypted string
            return dData;

        }
    }
}

Kada pokrenete navedeni program dobićete sličan rezultat ali ne i identičan. Svaki put kad pokrenete program i unesete isti tekst za enkriptovanje, dobićete drugačiji niz enkriptovanih byte podataka.

Enter some text you want to encrypt: Manuel Radovanovic www.manuelradovanovic.com

Encrypted text: 207, 161, 149, 190, 80, 185, 7, 53, 26, 234, 142, 170, 119, 211, 233, 143, 174, 207, 98, 49, 98, 125, 6, 123, 207, 245, 182, 136, 104, 235, 143, 254, 188, 40, 23, 198, 192, 202, 169, 83, 69, 39, 174, 48, 234, 112, 202, 226,

Decrypted text: Manuel Radovanovic www.manuelradovanovic.com

Press any key to continue...

Kako to sve izgleda možete pogledati i na video-u:


( C# 6.0 Tutorial - Advanced - 58. TripleDESCryptoServiceProvider Cryptography, Encrypt and Decrypt )

Kako da verifikujete digitalni potpis?

Algoritmi za šifrovanje javnim ključem se mogu iskoristiti i za digitalno potpisivanje podataka. Potpisivanje se vrši tako što se podaci prvo heširaju a zatim se na heširani algoritam primenjuje asimetrični algoritam. Asimetrična kriptografija za razliku od simetrične zahteva da kreirate par ključeva, jedan javni i jedan privatni ključ. Privatni ključ se čuva na tajnom mestu dok se javni distribuira. Čak i ako hacker presretne vaš javni ključ on se ne može dekriptovati bez privatnog ključa. Sledeći primer na najjednostavniji način prezentuje verifikaciju digitalnog potpisa.

using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Security.Cryptography;

namespace VerifiesDSAExample
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                // Create a new instance of DSACryptoServiceProvider
                DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();

                // The hash to sign
                byte[] Hash = { 64, 9, 253, 107, 82, 101, 147, 206, 215, 17, 229, 98, 30, 46, 105, 202, 218, 139, 135, 140 };

                // Create a DSASignatureFormatter object and pass it
                // the DSACryptoServiceProvider to transfer the key information
                DSASignatureFormatter dsaFormatter = new DSASignatureFormatter(dsa);

                // Set the hash algorithm to SHA1
                dsaFormatter.SetHashAlgorithm("SHA1");

                // Create a signature for HashValue and return it
                byte[] SignedHash = dsaFormatter.CreateSignature(Hash);

                // Create an DSASignatureDeformatter object and pass it
                // the DSACryptoServiceProvider to transfer the key information
                DSASignatureDeformatter dsaDeformatter = new DSASignatureDeformatter(dsa);

                // Verify the hash and display the results to the console
                if (dsaDeformatter.VerifySignature(Hash, SignedHash))
                {
                    WriteLine("The signature was verified.");

                }
                else
                {
                    WriteLine("The signature was not verified.");

                }
               
            }
            catch (CryptographicException ex)
            {
                WriteLine(ex.Message);

            }

            WriteLine(Environment.NewLine + "Press any key to continue...");
            ReadKey();
           
        }
    }
}

Kada pokrenete navedeni program dobićete identičan rezultat jer je digitalni potpis ispravan.

The signature was verified.

Press any key to continue...

Kako to sve izgleda možete pogledati i na video-u:


( C# 6.0 Tutorial - Advanced - 59. How to Verifies DSA - Digital Signature Algorithm )

Kako da enkriptujete i dekriptujete poruku koju šaljete koristeći ECDiffieHellmanCng klasu?

Klasa ECDiffieHellmanCng omogućava da dve osobe razmjenjuju privatni ključni materijal čak i ako komuniciraju putem javnog kanala. Obe strane mogu izračunati istu tajnu vrednost, koja se naziva tajnim sporazumom u Diffie-Hellman klasama. Tajni sporazum se onda može koristiti za različite svrhe, uključujući i simetrični ključ. Međutim, umjesto direktnog izlaganja tajnog sporazuma, klasa ECDiffieHellmanCng vrši neku naknadnu u obradi ugovora pre nego što obezbedi vrednost. Ova obrada podataka se naziva KDF - ključna funkcija derivacije. Vi možete odabrati koji KDF želite da koristite i podesite svoje parametre pomoću skupa svojstava. Pogledajte sledeći primer.

using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Cryptography;

class Person1
{
    public static byte[] Person1PublicKey;

    static void Main(string[] args)
    {
        Write("Enter some text you want to encrypt and send somebody: ");
        string message = ReadLine();

        using (ECDiffieHellmanCng ecd = new ECDiffieHellmanCng())
        {
            ecd.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
            ecd.HashAlgorithm = CngAlgorithm.Sha256;
            Person1PublicKey = ecd.PublicKey.ToByteArray();

            Person2 person2 = new Person2();

            CngKey k = CngKey.Import(person2.Person2PublicKey, CngKeyBlobFormat.EccPublicBlob);
            byte[] senderKey = ecd.DeriveKeyMaterial(CngKey.Import(person2.Person2PublicKey, CngKeyBlobFormat.EccPublicBlob));
            Send(senderKey, message, out byte[] encryptedMessage, out byte[] IV);
            person2.Receive(encryptedMessage, IV);

        }
    }

    public static void Send(byte[] key, string secretMessage, out byte[] encryptedMessage, out byte[] IV)
    {
        WriteLine(Environment.NewLine + Environment.NewLine + "Sending the message...");

        using (Aes aes = new AesCryptoServiceProvider())
        {
            aes.Key = key;
            IV = aes.IV;

            // Encrypt the message
            using (MemoryStream ms = new MemoryStream())
            using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
            {
                byte[] plainTextMessage = Encoding.UTF8.GetBytes(secretMessage);
                cs.Write(plainTextMessage, 0, plainTextMessage.Length);
                cs.Close();
                encryptedMessage = ms.ToArray();

            }
        }
    }
}

public class Person2
{
    public byte[] Person2PublicKey;
    private byte[] Key;

    public Person2()
    {
        using (ECDiffieHellmanCng ecd = new ECDiffieHellmanCng())
        {
            ecd.KeyDerivationFunction = ECDiffieHellmanKeyDerivationFunction.Hash;
            ecd.HashAlgorithm = CngAlgorithm.Sha256;
            Person2PublicKey = ecd.PublicKey.ToByteArray();
            Key = ecd.DeriveKeyMaterial(CngKey.Import(Person1.Person1PublicKey, CngKeyBlobFormat.EccPublicBlob));

        }

        WriteLine(Environment.NewLine + "Encrypted the message: " + Environment.NewLine);

        foreach (byte b in Key)
        {
            Write($"{b}, ");

        }

    }

    public void Receive (byte[] encryptedMessage, byte[] IV)
    {
        WriteLine("Receiving the message...");

        using (Aes aes = new AesCryptoServiceProvider())
        {
            aes.Key = Key;
            aes.IV = IV;

            // Decrypt and show the message
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms,aes.CreateDecryptor(),CryptoStreamMode.Write))
                {
                    cs.Write(encryptedMessage, 0, encryptedMessage.Length);
                    cs.Close();

                    string message = Encoding.UTF8.GetString(ms.ToArray());
                    WriteLine(Environment.NewLine);
                    WriteLine("Decrypted the message: ");
                    WriteLine(Environment.NewLine + message + Environment.NewLine);

                }
            }

            WriteLine(Environment.NewLine + "Press any key to continue...");
            ReadKey();

        }
    }
}

Kada pokrenete navedeni program dobićete sličan rezultat ali ne i identičan. Svaki put kad pokrenete program i unesete isti tekst za enkriptovanje, dobićete drugačiji niz enkriptovanih byte podataka.

Enter some text you want to encrypt and send somebody: www.manuelradovanovic.com

Encrypted the message:

221, 60, 191, 45, 36, 61, 7, 162, 38, 104, 148, 83, 103, 216, 102, 159, 23, 146, 21, 149, 110, 166, 110, 37, 1, 48, 60, 95, 225, 57, 78, 134,

Sending the message...
Receiving the message...

Decrypted the message:

www.manuelradovanovic.com

Press any key to continue...

Kako to sve izgleda možete pogledati i na video-u:


( C# 6.0 Tutorial - Advanced - 60. ECDiffieHellmanCng Cryptography, Encrypt and Decrypt )

Kako da enkriptujete i dekriptujete vaš code programa koristeći ToBase64Transform klasu?

Ovo je jednostavan primer kako možete enkriptovati vaš code programa u jedan fajl i dekriptovati ga u drugi koristeći članove ToBase64Transform klase. Inače Base 64 Content-Transfer-Encoding predstavlja proizvoljne bitne sekvence u obliku koji nisu čitljive čoveku. Pogledajte sledeći code:

using System;
using static System.Console;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Security.Cryptography;

namespace FromBase64TransformExample
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Protection protection = new Protection();

            string appPath = (Directory.GetCurrentDirectory());
            appPath = appPath + "..\\\\..\\\\..\\";

            // Insert your file names into this method call
            protection.EncodeFromFile(appPath + "program.cs", appPath + "code.enc");
            protection.DecodeFromFile(appPath + "code.enc", appPath + "roundtrip.txt");

            WriteLine(Environment.NewLine + "Press any key to continue...");
            ReadKey();

        }
       
    }

    class Protection
    {
        public void EncodeFromFile(string sourceFile, string targetFile)
        {
            // Verify members.cs exists at the specified directory
            if (!File.Exists(sourceFile))
            {
                Write("Unable to locate source file located at ");
                WriteLine($"{sourceFile}.");
                Write("Please correct the path and run the sample again.");

                return;

            }

            // Retrieve the input and output file streams
            using (FileStream inputFileStream = new FileStream(sourceFile, FileMode.Open, FileAccess.Read))
            {
                using (FileStream outputFileStream = new FileStream(targetFile, FileMode.Create, FileAccess.Write))
                {
                    // Create a new ToBase64Transform object to convert to base 64
                    ToBase64Transform base64Transform = new ToBase64Transform();

                    // Create a new byte array with the size of the output block size
                    byte[] outputBytes = new byte[base64Transform.OutputBlockSize];

                    // Retreive the file contents into a byte array
                    byte[] inputBytes = new byte[inputFileStream.Length];
                    inputFileStream.Read(inputBytes, 0, inputBytes.Length);

                    // Verify that multiple blocks can not be transformed
                    if (!base64Transform.CanTransformMultipleBlocks)
                    {
                        // Initialize the offset size
                        int inputOffset = 0;

                        // Iterate through inputBytes transforming by blockSize
                        int inputBlockSize = base64Transform.InputBlockSize;

                        while (inputBytes.Length - inputOffset > inputBlockSize)
                        {
                            base64Transform.TransformBlock(
                                inputBytes,
                                inputOffset,
                                inputBytes.Length - inputOffset,
                                outputBytes,
                                0);

                            inputOffset += base64Transform.InputBlockSize;
                            outputFileStream.Write(
                                outputBytes,
                                0,
                                base64Transform.OutputBlockSize);

                        }

                        // Transform the final block of data
                        outputBytes = base64Transform.TransformFinalBlock(
                            inputBytes,
                            inputOffset,
                            inputBytes.Length - inputOffset);

                        outputFileStream.Write(outputBytes, 0, outputBytes.Length);
                        WriteLine($"Created encoded file at {targetFile}");

                    }

                    // Dertemine if the current transform can be reused
                    if (!base64Transform.CanReuseTransform)
                    {
                        // Free up any used resources
                        base64Transform.Clear();

                    }
                }
            }
        }

        public void DecodeFromFile(string inFileName, string outFileName)
        {
            using (FromBase64Transform myTransform = new FromBase64Transform(FromBase64TransformMode.IgnoreWhiteSpaces))
            {
                byte[] myOutputBytes = new byte[myTransform.OutputBlockSize];

                // Open the input and output files
                using (FileStream myInputFile = new FileStream(inFileName, FileMode.Open, FileAccess.Read))
                {
                    using (FileStream myOutputFile = new FileStream(outFileName, FileMode.Create, FileAccess.Write))
                    {
                        // Retreive the file contents into a byte array
                        byte[] myInputBytes = new byte[myInputFile.Length];
                        myInputFile.Read(myInputBytes, 0, myInputBytes.Length);

                        // Transform the data in chunks the size of InputBlockSize
                        int i = 0;
                        while (myInputBytes.Length - i > 4) // *myTransform.inputBlockSize*/
                        {
                            int bytesWritten = myTransform.TransformBlock(myInputBytes, i, 4, myOutputBytes, 0);
                            i += 4;
                            myOutputFile.Write(myOutputBytes, 0, bytesWritten);

                        }

                        // Transform the final block of data
                        myOutputBytes = myTransform.TransformFinalBlock(myInputBytes, i, myInputBytes.Length - i);
                        myOutputFile.Write(myOutputBytes, 0, myOutputBytes.Length);

                        // Free up any used resources
                        myTransform.Clear();

                    }
                }
            }
        }
    }
}

Pokrenite program zatim pogledajte code.enc fajl i roundtrip.txt u direktorijumu vašeg programa. Sličan sadržaj će te dobiti u code.enc fajlu:


( Sadržaj code.enc fajl-a )

Kako to sve izgleda možete pogledati i na video-u:


( C# 6.0 Tutorial - Advanced - 61. How to Decodes a Base 64 - Encoded File to a Text File )

Ovo su bili prvih 10 primera od 29 koji će vas definitivno osposobiti za enkriptovanje i dekriptovanje podataka. Nastavak sledi u sledećem 2 delu istog naziva posta.