Files
Common-VS2019/SacsStandardBase/Base/Helpers/SacsEncryptionHelper.cs
T
2021-05-05 15:36:28 +01:00

129 lines
4.4 KiB
C#

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
{
//-------------------------------------------------------------------
/// <summary>Number of byes in key. [32 bytes = 256 bits]</summary>
public static int KeyLength { get; } = 32;
/// <summary>Default encoding: UTF8.</summary>
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);
}
//-------------------------------------------------------------------
}
//=======================================================================
}