I'm having some issues when I try to decrypt a string in c# wasm using js interop. I'm new to encryption/decryption so I am unsure of what the error is actually saying. I have stepped through my code and logged the keys, iv and other items and seems they are the proper values.
Here is the code I have.
Blazor page
Encryption.razor
<div class="input-container">
<label for="plainText">Input string</label>
<div class="input-wrapper">
<input id="plainText" type="text" @bind="plainText" title="Input string" />
</div>
</div>
<div class="button-container">
<button @onclick="Encrypt" class="button-style button-one">Encrypt</button>
<button @onclick="Decrypt" class="button-style">Decrypt</button>
</div>
<div class="input-container">
<label for="encryptedMessage">Encrypted/Decrypted Message</label>
<div class="input-wrapper">
<input id="encryptedMessage" type="text" @bind="encryptedMessage" />
</div>
</div>
@code {
private string plainText = "";
private string encryptedMessage = "";
private string keyBase64 = "";
private string ivBase64 = "";
// Method to generate a key and IV
private async Task GenerateKeyAndIV()
{
keyBase64 = await JSRuntime.InvokeAsync<string>("generateKey");
ivBase64 = await JSRuntime.InvokeAsync<string>("generateIV");
}
private async Task Encrypt()
{
await GenerateKeyAndIV();
encryptedMessage = await encryptionService.Encrypt(plainText, keyBase64, ivBase64);
}
private async Task Decrypt()
{
await GenerateKeyAndIV();
plainText = await encryptionService.Decrypt(encryptedMessage, keyBase64, ivBase64);
}
// Call GenerateKeyAndIV when the component is initialized
protected override async Task OnInitializedAsync()
{
await GenerateKeyAndIV();
}
EncryptionService.cs
using Microsoft.JSInterop;
using System.Threading.Tasks;
public class EncryptionService
{
private readonly IJSRuntime _jsRuntime;
public EncryptionService(IJSRuntime jsRuntime)
{
_jsRuntime = jsRuntime;
}
public async Task<string> Encrypt(string text, string keyBase64, string iv)
{
return await _jsRuntime.InvokeAsync<string>("encryptText", text, keyBase64, iv);
}
public async Task<string> Decrypt(string encryptedBase64, string keyBase64, string iv)
{
return await _jsRuntime.InvokeAsync<string>("decryptText", encryptedBase64, keyBase64, iv);
}
}
index.html scripts
<script>
window.generateKey = async () => {
const key = await crypto.subtle.generateKey(
{ name: 'AES-GCM', length: 128 },
true,
['encrypt', 'decrypt']
);
const keyBytes = await crypto.subtle.exportKey('raw', key);
return btoa(String.fromCharCode.apply(null, new Uint8Array(keyBytes)));
};
</script>
<!-- Function to generate IV -->
<script>
window.generateIV = async () => {
const iv = crypto.getRandomValues(new Uint8Array(12));
return btoa(String.fromCharCode.apply(null, iv));
};
</script>
<!-- Function to encrypt text using AES-GCM algorithm -->
<script>
async function encryptText(text, keyBase64, ivBase64) {
const iv = new Uint8Array(atob(ivBase64).split('').map(char => char.charCodeAt(0)));
const keyBytes = new Uint8Array(atob(keyBase64).split('').map(char => char.charCodeAt(0)));
const encodedText = new TextEncoder().encode(text);
const encodedKey = await crypto.subtle.importKey("raw", keyBytes, "AES-GCM", false, ["encrypt"]);
const encryptedBytes = await crypto.subtle.encrypt({ name: "AES-GCM", iv }, encodedKey, encodedText);
return btoa(String.fromCharCode.apply(null, new Uint8Array(encryptedBytes)));
}
</script>
<!-- Function to decrypt text using AES-GCM algorithm -->
<script>
async function decryptText(encryptedBase64, keyBase64, ivBase64) {
const iv = new Uint8Array(atob(ivBase64).split('').map(char => char.charCodeAt(0)));
const keyBytes = new Uint8Array(atob(keyBase64).split('').map(char => char.charCodeAt(0)));
const encryptedBytes = new Uint8Array(atob(encryptedBase64).split('').map(char => char.charCodeAt(0)));
const importedKey = await crypto.subtle.importKey("raw", keyBytes, "AES-GCM", false, ["decrypt"]);
const decryptedBytes = await crypto.subtle.decrypt({ name: "AES-GCM", iv }, importedKey, encryptedBytes);
return new TextDecoder().decode(decryptedBytes);
}
</script>
I have logged the values and they seem correct. I have tried consulting chatGPT on the error but it doesn't specificy what exactly the issue is in the decrypt function.
