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
CryptoKeyDescriptor
for long-living keys. - Dispose a
CryptoKeyDescriptor
to delete the underlyingCryptoKey
in thejavascript
runtime.
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
this
keyword 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
samples
to add more examples + possibility to load the keys of MDN examples too. - A documentation for
cryptography
objects. - Rework the
test
application 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.