Symmetric Key Algorithm | Description |
---|---|
Advanced Encryption Standard | Offers a key size of 128, 192, or 256 bits. |
Rijndael | Similar to AES but offers more key size options. |
Triple-DES | The successor to DES. Its key length is 168 bits, but the effective security it provides is 112-bit. |
Data Encryption Standard | Considered insecure because it uses only the 56 bits key size which can be broken in a few hours. |
Asymmetric Key Algorithm | Description |
---|---|
Rivest Shamir Adleman | Used for digital signatures as well as encryption in e-commerce protocols; incorporated into all major Web browsers; the basis for Secure Socket Layer (SSL). |
Digital Signature Algorithm | Used for digital signatures. |
Elliptic Curve DSA | More secure, with shorter key sizes, for example: ECDSA 160 bits is as secure as DSA 1024 bits. |
EC Diffie-Hellman | Used to exchange private keys in a secure way over a public channel. |
Hash Algorithm | Description |
---|---|
Secure Hash Algorithm | stronger than MD5 against brute force attacks - SHA1 uses a 160-bit hash size - SHA256 uses 256 bits - SHA384 uses 384 bits - SHA512 uses 512 bits; it is the strongest and the slowest from the SHA algorithms |
Message Digest Algorithm 5 | faster than SHA; MD5 uses 128-bit hash size |
RACE Integrity Primitives Evaluation MD | RIPEDM160 uses a 160-bit hash size |
The .NET Framework contains classes for encryption in the namespace System.Security.Cryptography. The classes with a Cng (Cryptography Next Generation) prefix or suffix are newer versions of the native Crypto API. There are a few abstract classes such as MD5, SHA1, or DES. The classes with the suffix CryptoServiceProvider implement the abstract base classes.
Category | Abstract Base Class | Concrete Classes |
---|---|---|
Symmetric | DES | DESCryptoServiceProvider |
TripleDES | TripleDESCryptoServiceProvider | |
Aes | AesCryptoServiceProvider, AesManaged | |
RC2 | RC2CryptoServiceProvider | |
Rijandel | RijandelManaged | |
Asymmetric | DSA | DSACryptoServiceProvider |
ECDsa | ECDsaCng, ECDiffieHellman, ECDiffieHellmanCng | |
RSA | RSACryptoServiceProvider | |
Hash | MD5 | MD5Cng |
SHA1 | SHA1Managed, SHA1Cng | |
SHA256 | SHA256Managed, SHA256Cng | |
SHA384 | SHA384Managed, SHA384Cng | |
SHA512 | SHA512Managed, SHA512Cng | |
RIPEMD160 | RIPEMD160Managed |
Digital certificates can be used to verify the authenticity of an author. Digital certificates use hashing as well as asymmetric encryption. A digital certificate authenticates the identity of an object signed by the certificate. It also helps with protecting the integrity of data.
An example of communication using a digital certificate. A is sending a message to B:
A digital certificate is part of a Public Key Infrastructure (PKI). A PKI is a system of digital certificates, certificate authorities, and other registration authorities that authenticate and verify the validity of each involved party.
A Certificate Authority (CA) is a third-party issuer of certificates that is considered trustworthy by all parties. The CA issues certificates (certs) that contain a public key, a subject to which the certificate is issued, and the details of the CA.
One use of digital certificates is to secure Internet communication. The HTTPS communication protocol is used to secure communication between a web server and a client.
The makecert.exe utility can be used to create X.509 certificates for test purposes. Before the certificate can be used it has to be installed in a certificate store.
Generate a certificate to the MyCert.cer file:
makecert MyCert.cer
Create and install a certificate in a custom certificate store MyCertStore:
makecert -n "CN = WBS" -sr currentuser -ss MyCertStore
The ProtectedData and ProtectedMemory classes are managed wrappers around Data Protection Application Programming Interface (DPAPI):
The ProtectedData.Protect method does not modify the input data. The ProtectedMemory.Protect method modifies the input data. The length of the input byte array has to be a multiple of 16.
Example: Encrypt and decrypt a string using the symmetric key algorithm AES:
using System; using System.IO; using System.Security.Cryptography; namespace WBS.Test { public class TestApp { public static int Main(string[] args) { string original = "A secret message"; using (SymmetricAlgorithm sa = new AesManaged()) { byte[] encrypted = Encrypt(sa, original); string roundtrip = Decrypt(sa, encrypted); // Displays: A secret message Console.WriteLine("Original: {0}", original); Console.WriteLine("Round Trip: {0}", roundtrip); } return 0; } static byte[] Encrypt(SymmetricAlgorithm aes, string plainText) { // Use the SymmetricAlgorithm.CreateEncryptor method to create an encryptor. ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV); using (MemoryStream memStream = new MemoryStream()) { // Encrypt a byte sequence using the CryptoStream class. using (CryptoStream crStream = new CryptoStream(memStream, encryptor, CryptoStreamMode.Write)) { using (StreamWriter writer = new StreamWriter(crStream)) { writer.Write(plainText); } return memStream.ToArray(); } } } static string Decrypt(SymmetricAlgorithm aes, byte[] cipherText) { // Use the SymmetricAlgorithm.CreateDecryptor method to create a decryptor. ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV); using (MemoryStream memStream = new MemoryStream(cipherText)) { // Decrypt a byte sequence using the CryptoStream class. using (CryptoStream crStream = new CryptoStream(memStream, decryptor, CryptoStreamMode.Read)) { using (StreamReader reader = new StreamReader(crStream)) { return reader.ReadToEnd(); } } } } } }
Example: Use asymmetric encryption with RSACryptoServiceProvider to encrypt data using a public key and decrypt it with a private key:
using System; using System.Security.Cryptography; using System.Text; namespace WBS.Test { public class TestApp { public static int Main(string[] args) { // Create a public/private key pair. string publicKeyXML, privateKeyXML; using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { publicKeyXML = rsa.ToXmlString(false); // export the public key privateKeyXML = rsa.ToXmlString(true); // export both the public and the private keys } // Obtain byte representation of data for encryption. UnicodeEncoding converter = new UnicodeEncoding(); byte[] dataToEncrypt = converter.GetBytes("A secret message"); // Use the public key to encrypt data. byte[] encryptedData; using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { rsa.FromXmlString(publicKeyXML); // we need only the public key to encrypt data encryptedData = rsa.Encrypt(dataToEncrypt, false); } // Use the private key to decrypt data. byte[] decryptedData; using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { rsa.FromXmlString(privateKeyXML); decryptedData = rsa.Decrypt(encryptedData, false); } // Obtain text representation of the byte sequence. string decryptedString = converter.GetString(decryptedData); Console.WriteLine(decryptedString); // displays: A secret message return 0; } } }
Example: Configure RSACryptoServiceProvider to use a key container for saving and loading the asymmetric key. The key container can be specific to a user or to the whole machine:
using System.Security.Cryptography; using System.Text; namespace WBS.Test { public class TestApp { public static int Main(string[] args) { // Obtain byte representation of data for encryption. UnicodeEncoding converter = new UnicodeEncoding(); byte[] dataToEncrypt = converter.GetBytes("A secret message"); CspParameters csp = new CspParameters() { KeyContainerName = "MyContainer" }; byte[] encryptedData; using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(csp)) { encryptedData = rsa.Encrypt(dataToEncrypt, false); } return 0; } } }
Example: Export both the public and the private keys to XML:
using System; using System.Security.Cryptography; namespace WBS.Test { public class TestApp { public static int Main(string[] args) { RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); string publicKeyXML = rsa.ToXmlString(false); // export the public key string privateKeyXML = rsa.ToXmlString(true); // export both the public and the private keys Console.WriteLine(publicKeyXML); Console.WriteLine(privateKeyXML); return 0; } } }
Example: Calculate the hash code for a piece of text using the SHA256Managed algorithm. The hashing algorithm SHA256Managed outputs a significantly different hash code for a small change in data:
using System; using System.Linq; // SequenceEqual using System.Security.Cryptography; using System.Text; namespace WBS.Test { public class TestApp { public static int Main(string[] args) { UnicodeEncoding byteConverter = new UnicodeEncoding(); SHA256 sha = SHA256.Create(); string str = "Sample text"; byte[] hash1 = sha.ComputeHash(byteConverter.GetBytes(str)); // hash2 is defferent than hash1 str = "Modified sample text"; byte[] hash2 = sha.ComputeHash(byteConverter.GetBytes(str)); // hash3 is the same as hash1 str = "Sample text"; byte[] hash3 = sha.ComputeHash(byteConverter.GetBytes(str)); // Check whether the string str has been altered by comparing the hash codes. Console.WriteLine(hash1.SequenceEqual(hash2)); // Displays: false Console.WriteLine(hash1.SequenceEqual(hash3)); // Displays: true return 0; } } }
Example: Use a digital certificate to sign and verify some text. The data is hashed and then signed. When verifying, the same hash algorithm is used to make sure the data has not changed:
using System; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Text; namespace WBS.Test { public class TestApp { public static int Main(string[] args) { // Sign and verify data with a certificate string textToSign = "Test paragraph"; byte[] signature = Sign(textToSign, "CN = WBS"); // Uncomment this line to make the verification step fail //signature[0] = 0; Console.WriteLine(Verify(textToSign, signature)); // displays: True return 0; } // The Sign method uses the private key of the certificate to // create a signature for the data. static byte[] Sign(string text, string certSubject) { X509Certificate2 cert = GetCertificate(); var csp = (RSACryptoServiceProvider)cert.PrivateKey; byte[] hash = HashData(text); return csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA1")); } // The Verify method uses the public key of the certificate to // see whether the data has changed. static bool Verify(string text, byte[] signature) { X509Certificate2 cert = GetCertificate(); var csp = (RSACryptoServiceProvider)cert.PublicKey.Key; byte[] hash = HashData(text); return csp.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA1"), signature); } private static byte[] HashData(string text) { HashAlgorithm hashAlgorithm = new SHA1Managed(); UnicodeEncoding encoding = new UnicodeEncoding(); byte[] data = encoding.GetBytes(text); byte[] hash = hashAlgorithm.ComputeHash(data); return hash; } private static X509Certificate2 GetCertificate() { X509Store my = new X509Store("MyCertStore", StoreLocation.CurrentUser); my.Open(OpenFlags.ReadOnly); var certificate = my.Certificates[0]; return certificate; } } }
Example: Generate an encrypted representation of a byte array using DPAPI:
using System; using System.Security.Cryptography; namespace CSharpTest { class EntryPoint { public static void Main() { byte[] secretData = new byte[] { 120, 34, 56, 88, 230, 23, 45, 89, 34, 234, 106, 78, 46, 203, 109, 3}; // Only the current user can decrypt the data. // The input byte array is not modified. byte[] data1 = ProtectedData.Protect(secretData, null, DataProtectionScope.CurrentUser); // Any user on the current computer can decrypt the data. It is useful when data is // stored on a network share and there are multiple users on the same computer who // need access the data. // The input byte array is not modified. byte[] data2 = ProtectedData.Protect(secretData, null, DataProtectionScope.LocalMachine); // Only the user who encypted data can decrypt it. // The input byte array is modified. ProtectedMemory.Protect(secretData, MemoryProtectionScope.SameLogon); // All threads in the same process can decrypt the data. // The input byte array is modified. ProtectedMemory.Protect(secretData, MemoryProtectionScope.SameProcess); } } }
Links