129 lines
4.4 KiB
C#
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);
|
|
}
|
|
|
|
//-------------------------------------------------------------------
|
|
}
|
|
//=======================================================================
|
|
}
|