I am creating Blazor WebAssembly App and trying to figure how can i Encrypt/Protect data stored in Session Storage/ Local Storage ?
First things that you need to know is that blazor wasm model till .net 5 does not support crypto library. (as my knowledge)
in .net 6 you can use Blazor.SubtleCrypto
but you can inject AES method into it with javascript interop, follow these steps:
function encryptedText(inputSrt, keyArray) {
var textBytes = aesjs.utils.utf8.toBytes(inputSrt);
var aesCtr = new aesjs.ModeOfOperation.ctr(keyArray, new aesjs.Counter(5));
var encryptedBytes = aesCtr.encrypt(textBytes);
return aesjs.utils.hex.fromBytes(encryptedBytes);
}
function decryptText(inputStr, keyArray) {
var encryptedBytes = aesjs.utils.hex.toBytes(inputStr);
var aesCtr = new aesjs.ModeOfOperation.ctr(keyArray, new aesjs.Counter(5));
var decryptedBytes = aesCtr.decrypt(encryptedBytes);
return aesjs.utils.utf8.fromBytes(decryptedBytes);
}
now your are ready. add DI interface to .NetCore follow these steps:
public interface IEncryptProvider
{
string TextEncrypt(string input);
string TextDecrypt(string input);
string Encrypt<T>(T input);
T Decrypt<T>(string input);
}
public class AesJsProvider : IEncryptProvider
{
IJSRuntime GetJSRuntime;
public static int[] HiddenKey = new int[] { 0, 45, 6, 3, 8, 5, 8, 7, 89, 7, 10, 21, 12, 34, 12, 1 };
public static string JsEncryptMethod { get; set; } = "encryptText";
public static string JsDecryptMethod { get; set; } = "decryptText";
public AesJsProvider(IJSRuntime jSRuntime)
{
GetJSRuntime = jSRuntime;
}
public async Task<string> TextDecrypt(string input)
{
if (string.IsNullOrEmpty(input))
return string.Empty;
try
{
return await GetJSRuntime.InvokeAsync<string>(JsEncryptMethod, input, HiddenKey);
}
catch (Exception)
{
return string.Empty;
}
}
public async Task<string> TextEncrypt(string input)
{
if (string.IsNullOrEmpty(input))
return string.Empty;
try
{
return await GetJSRuntime.InvokeAsync<string>(JsDecryptMethod, input, HiddenKey);
}
catch (Exception)
{
return string.Empty;
}
}
public async Task<string> Encrypt<T>(T input)
{
var str = JsonSerializer.Serialize(input);
if (input == null)
return string.Empty;
try
{
return await GetJSRuntime.InvokeAsync<string>(JsEncryptMethod, input, HiddenKey);
}
catch (Exception)
{
return string.Empty;
}
}
public async Task<T> Decrypt<T>(string input)
{
var str = await TextDecrypt(input);
if (string.IsNullOrEmpty(input))
return default(T);
try
{
return await GetJSRuntime.InvokeAsync<T>(JsDecryptMethod, input, HiddenKey);
}
catch (Exception)
{
return default;
}
}
}
so all of codes completed, lets config startup options
services.AddSingleton<IEncryptProvider, JSRuntimeProvider>();
you can change change HiddenKey as your need to a secret key in provider, and inject IEncryptProvider on any page to encrypt/decrypt string or objects
source code available in github: https://github.com/mahdiit/blazor-wasm-encryptstorage