A convenient way to use browser cryptography from Blazor.
As a C# developer (and sometimes Angular), when I started Blazor I was frustrated with not having
any easy way to interact with cryptography operations proposed by SubtleCrypto.
As System.Security.Cryptography namespace is very limited in support into web-browsers,
this library aims at giving some quick access and C# idiomatic methods to work with
web-browser cryptography.
Some resources on which this library is based:
CryptoKey we are used to work with from javascript runtime are living inside
the javascript runtime, and C# works with them using CryptoKeyDescriptor.
This allows conserving the maximum benefits of the browser runtime, including
the extractable property of the keys.
More details can be found in the readme of the src/interfaces directory.
This library was design to work with Blazor in a very easy way and few configuration. The two main namespaces of the library are:
interfaces: low-levelC#classes close to the Web Cryptography API interfaces.cryptography: high-levelC#classes that are use to abstract the implementation details of the Web Cryptography API.
Samples of code will be added progressively into the samples project, where the folder Pages will contains the actual code.
Caution: at the moment, this library was only tested with
Blazor WASM)
With cryptography namespace, you can encrypt data with AES like this:
- Inject the AES factory into the app.
// Program.cs
using Glihm.JSInterop.Browser.WebCryptoAPI.Cryptography.AES;
...
builder.Services.AddWebCryptoAes();- Request the service into any blazor component requiring AES.
// BlazorComponent.razor
@using Glihm.JSInterop.Browser.WebCryptoAPI.Cryptography.AES
@inject AesFactory _aesFactory
...
private async ValueTask<byte[]?>
EncryptData(byte[] key, byte[] plaintext, byte[] iv)
{
await using AesGcm? aesGcm = await this._aesFactory.Create<AesGcm>(key);
if (aesGcm is not null)
{
return await aesGcm.Encrypt(plaintext, iv);
}
}I am working on a documentation to show examples for all the web crypto API. In the meanwhile, feel free to take a look at the cryptography test code which has some basic usecase I used to test the implementation.
As you can notice, the last example is making use of await using.
In fact, as the CryptoKey are managed by javascript runtime,
they are considered unmanaged resources for C#.
You can find more information about this in the src/interfaces readme.
For memory-efficient usage, you can:
- Keep a reference on the
CryptoKeyDescriptorfor long-living keys. - Dispose a
CryptoKeyDescriptorto delete the underlyingCryptoKeyin thejavascriptruntime.
The library is (for now) only limiting the possibilities you have to pass wrong argument to the cryptography operations. But clearly, the library is not checking for all the arguments you pass to the Web Cryptography API.
Please be aware of that, and refer to the following documentation for more exhaustive details:
Also, this library is not responsible for the key managment on your cryptography designs. This is the application responsability to efficiently and correctly handle it's cryptographic keys lifecycle. You can check this link given from MDN documentation about cryptography basics.
Any issue/PR are very welcome to keep improving this tool.
Basic rules are the one we can find in major repositories:
- Short commit sentence: imperative, all lower case no punctuation.
- Longer commit description: written english, with punctuation.
- Small commits if it's possible, to keep changes very localized.
I am trying to follow dotnet runtime coding style rules but with some slight variations:
- Always use
thiskeyword to refer to an instance field/property/method. - Don't use
s_ort_prefix for static fields. - I personally never use
var, but not against if it follows the coding style linked above. - I always have two lines for methods declaration because of the
C#huge name's length for some types:- First line with access modifiers and return type.
- Second line with method name and arguments.
You can find a .editorconfig file with the configuration I generated with VS studio.
I am personally using other editors, but please let me know if you have issue with it.
Even if I try to be as consistent as I can, don't hesitate to report any issue.
You can find the package on NuGet.
- continue
samplesto add more examples + possibility to load the keys of MDN examples too. - A documentation for
cryptographyobjects. - Rework the
testapplication to be more in "unit testing" fashion. As it more a "bulk test" for now. - Test the compatibility with
Blazor Server. - Add CI with GitHub action to publish the package.