More organizations today understand that sensitive information should be stored encrypted in their repositories (Examples: user passwords, credit cards, SSN etc). Also there are regulations and security standards such as the PCI:DSS which requires the encryption of credit card numbers.
Thus, developers in such organizations encounter the issues of encryption frequently and are required to find appropriate solutions.
There are a lot of ways to encrypt/decrypt information by using buld-in .NET libraries for encryption.
I decided to present you here the shortest way that i found for doing that.
The following code is an example of the short way to encrypt/decrypt data using AES algorithm.
Please notice that in this example i stored the encryption key in the code, but of course in the real life the key should be stored in a secure repository with appropriate ACL privileges.
using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Security.Cryptography; namespace aes3 { class aes3 { static void Main(string[] args) { RijndaelManaged AesEncryption = new RijndaelManaged(); string plainStr = "AES me"; // The text that would be encrypted AesEncryption.KeySize = 256; // 192, 256 AesEncryption.BlockSize = 128; AesEncryption.Mode = CipherMode.CBC; AesEncryption.Padding = PaddingMode.PKCS7; // The key should be generated prior and also should be stored in secure repository // with appropriate ACL priviledges. string keyStr = "cGFzc3dvcmQAAAAAAAAAAA=="; string ivStr = "cGFzc3dvcmQAAAAAAAAAAA=="; byte[] ivArr = Convert.FromBase64String(keyStr); byte[] keyArr = Convert.FromBase64String(ivStr); AesEncryption.IV = ivArr; AesEncryption.Key = keyArr; // This array will contain the plain text in bytes byte[] plainText = ASCIIEncoding.UTF8.GetBytes(plainStr); // Creates Symmetric encryption and decryption objects ICryptoTransform crypto = AesEncryption.CreateEncryptor(); ICryptoTransform decrypto = AesEncryption.CreateDecryptor(); // The result of the encrypion and decryption byte[] cipherText = crypto.TransformFinalBlock(plainText, 0, plainText.Length); byte[] decryptedText = decrypto.TransformFinalBlock(cipherText,0,cipherText.Length); Console.Write("The plain text\"{0}\" in the encrypted format is:{1} \n",plainStr,Convert.ToBase64String(cipherText)); Console.Write("The encrypted text \"{0}\" is decrypted to: {1}",Convert.ToBase64String(cipherText), ASCIIEncoding.UTF8.GetString(decryptedText)); Console.Read(); } } }
very useful, thank you !
ReplyDeleteThx...
ReplyDeleteYossi, thanks for posting but I should let you know this isn't production-ready. I like that you use the TransformFinalBlock method to write the transformed data - other examples online add unnecessary MemoryStreams and/or Cryptostreams, but you need to use a password-based key derivation function to create the hash and salt (PBKDF) for your RijndaelManaged/AesManaged instance. For example:
ReplyDelete```
// ...
Rfc2898DeriveBytes key = new Rfc2898DeriveBytes(password, 32, 10000); //use some sufficiently long and random password stored elsewhere
AesEncryption.Key = key.GetBytes(32);
AesEncryption.IV = key.GetBytes(16);
//...
```
More on this subject here - https://www.owasp.org/index.php/Using_Rfc2898DeriveBytes_for_PBKDF2.
Then store the unique salt somewhere with the encrypted data for decrypting later. Many times this is a Salt column in the same data row as the encrypted data.
Here is a repository with good code for reference and usage, with the best cryptographic practices -> https://github.com/alecgn/crypthash-net
ReplyDelete