using Sarand.Net.Standard.Base.Core; using Sarand.Net.Standard.Base.Utils; using System; using System.Collections.Generic; using System.Security.Cryptography; using System.Text; namespace Sarand.Net.Standard.Base.Helpers { //======================================================================= public static class SacsEncryptionHelper { //------------------------------------------------------------------- /// Number of byes in key. [32 bytes = 256 bits] public static int KeyLength { get; } = 32; /// Default encoding: UTF8. public static Encoding DefaultEncoding { get; } = Encoding.UTF8; //------------------------------------------------------------------- // Symmetric Encryption in .NET Core // System.Security.Cryptography implements and provides the APIs for encryption in .NET Core. // Ref. https://damienbod.com/2020/08/19/symmetric-and-asymmetric-encryption-in-net-core/ //------------------------------------------------------------------- public static bool IsBase64(String value, int expectedLength = 0) { try { Byte[] decoded = Convert.FromBase64String(value); if (expectedLength > 0 && decoded.Length != expectedLength) return false; } catch (Exception) { return false; } return true; } public static String EncodePlainKey(String plainKey, int keyLength = 32, Encoding encoding = null) { if (StringUtil.IsEmpty(plainKey)) throw new NotSupportedException("Plain key must not be null/blank"); // Ensure key if 32 bytes long. while (StringUtil.GetLength(plainKey) < keyLength) plainKey += plainKey; plainKey = StringUtil.Left(plainKey, keyLength); // Encode to base-64. encoding = encoding ?? DefaultEncoding; return Convert.ToBase64String(encoding.GetBytes(plainKey)); } //------------------------------------------------------------------- // Generate random key and IV. // NB Can use own key if suitable - 32 character value in base-64 format. public static String InitSymmetricEncryptionKey() { var key = GetEncodedRandomString(KeyLength); // 256 bits. return key; } public static string InitSymmetricEncryptionIV(String key) { Aes cipher = CreateCipher(key); var IVBase64 = Convert.ToBase64String(cipher.IV); return IVBase64; } public static (string Key, string IVBase64) InitSymmetricEncryptionKeyIV() { var key = InitSymmetricEncryptionKey(); var IVBase64 = InitSymmetricEncryptionIV(key); return (key, IVBase64); } //------------------------------------------------------------------- public static string GetEncodedRandomString(int length) { var base64 = Convert.ToBase64String(GenerateRandomBytes(length)); return base64; } private static Aes CreateCipher(string keyBase64) { // Default values: Keysize 256 bits, Padding PKC27. Aes cipher = Aes.Create(); // Ensure the integrity of the ciphertext if using CBC cipher.Mode = CipherMode.CBC; cipher.Padding = PaddingMode.ISO10126; byte[] rawKey = Convert.FromBase64String(keyBase64); String rawKeyValue = System.Text.Encoding.Default.GetString(rawKey); cipher.Key = rawKey; return cipher; } private static byte[] GenerateRandomBytes(int length) { var byteArray = new byte[length]; SacsRandomHelper.Fill(byteArray); return byteArray; } //------------------------------------------------------------------- public static string Encrypt(string text, string IV, string key) { Aes cipher = CreateCipher(key); cipher.IV = Convert.FromBase64String(IV); ICryptoTransform cryptTransform = cipher.CreateEncryptor(); byte[] plaintext = Encoding.UTF8.GetBytes(text); byte[] cipherText = cryptTransform.TransformFinalBlock(plaintext, 0, plaintext.Length); return Convert.ToBase64String(cipherText); } //------------------------------------------------------------------- public static string Decrypt(string encryptedText, string IV, string key) { Aes cipher = CreateCipher(key); cipher.IV = Convert.FromBase64String(IV); ICryptoTransform cryptTransform = cipher.CreateDecryptor(); byte[] encryptedBytes = Convert.FromBase64String(encryptedText); byte[] plainBytes = cryptTransform.TransformFinalBlock(encryptedBytes, 0, encryptedBytes.Length); return Encoding.UTF8.GetString(plainBytes); } //------------------------------------------------------------------- } //======================================================================= }