( 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.
These were the first 10 examples out of 29 that will definitely train you to encrypt and decrypt data. The continuation follows in the next 2 parts of the post of the same name.
ReplyDeleteWHERE ARE THE OTHER 19 EXAMPLES ... ??
It's not finished... but there are videos on YouTube.... Playlist C# Advanced ... https://www.youtube.com/watch?v=3kMBtWrar9M&list=PLvxwy-1qpkBmWFktBU7i3uHIS4aMfIDAy ..
ReplyDelete