You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET Core Blazor WebAssembly中SubtleCrypto如何使用自定义密钥?

在Blazor WebAssembly中使用用户自定义密钥集成SubtleCrypto

你不需要依赖启动时配置的固定密钥,完全可以根据用户输入动态生成可用的加密密钥,核心是绕开全局配置的限制,直接通过ISubtleCrypto提供的API手动导入/生成密钥。

实现步骤

  1. 调整全局服务注册
    如果之前在Program.cs中配置了固定密钥,可以删除该配置,或者保留但不设置opt.Key,后续按需处理:

    // Program.cs中只注册服务,不固定密钥
    builder.Services.AddSubtleCrypto();
    
  2. 在组件中动态处理用户密钥
    在需要加密/解密的组件中注入ISubtleCrypto,接收用户输入的密钥后,将其转换为符合加密算法要求的CryptoKey对象(SubtleCrypto的核心操作依赖该对象,而非原始字符串)。

完整代码示例

组件UI(Razor部分)

<div>
    <label>加密密钥:</label>
    <input @bind="userInputKey" type="password" placeholder="输入密钥" />
    <button @onclick="HandleEncrypt">加密测试内容</button>
    <button @onclick="HandleDecrypt">解密内容</button>
    <p>加密结果: @encryptedBase64</p>
    <p>解密结果: @decryptedText</p>
</div>

组件逻辑(C#部分)

@inject ISubtleCrypto SubtleCrypto
@using System.Text

private string userInputKey = string.Empty;
private string encryptedBase64 = string.Empty;
private string decryptedText = string.Empty;

// 加密逻辑
private async Task HandleEncrypt()
{
    if (string.IsNullOrWhiteSpace(userInputKey))
    {
        encryptedBase64 = "请输入有效密钥";
        return;
    }

    // 1. 将用户输入的密钥转为字节数组,并用SHA-256哈希得到32字节的AES-256密钥材料
    var rawKeyBytes = Encoding.UTF8.GetBytes(userInputKey);
    var hashedKey = await SubtleCrypto.DigestAsync("SHA-256", rawKeyBytes);

    // 2. 导入密钥为AES-GCM算法可用的CryptoKey
    var cryptoKey = await SubtleCrypto.ImportKeyAsync(
        KeyFormat.Raw,
        hashedKey,
        new AesKeyAlgorithm("AES-GCM"),
        extractable: false, // 设置为false避免密钥被导出
        new[] { KeyUsage.Encrypt, KeyUsage.Decrypt });

    // 3. 生成随机IV(AES-GCM推荐12字节,每次加密都用新IV)
    var iv = Crypto.GetRandomValues(new byte[12]);

    // 4. 加密目标数据
    var plaintextBytes = Encoding.UTF8.GetBytes("这是需要加密的敏感内容");
    var encryptedBytes = await SubtleCrypto.EncryptAsync(
        new AesGcmParams { Iv = iv },
        cryptoKey,
        plaintextBytes);

    // 5. 将IV和加密结果合并(IV无需保密,和密文一起存储)
    var combinedData = iv.Concat(encryptedBytes).ToArray();
    encryptedBase64 = Convert.ToBase64String(combinedData);
}

// 解密逻辑
private async Task HandleDecrypt()
{
    if (string.IsNullOrWhiteSpace(userInputKey) || string.IsNullOrWhiteSpace(encryptedBase64))
    {
        decryptedText = "请输入密钥并确保有加密内容";
        return;
    }

    try
    {
        var combinedData = Convert.FromBase64String(encryptedBase64);
        // 提取IV(前12字节)和密文
        var iv = combinedData.Take(12).ToArray();
        var encryptedBytes = combinedData.Skip(12).ToArray();

        // 重新导入密钥(和加密时的哈希逻辑一致)
        var rawKeyBytes = Encoding.UTF8.GetBytes(userInputKey);
        var hashedKey = await SubtleCrypto.DigestAsync("SHA-256", rawKeyBytes);
        var cryptoKey = await SubtleCrypto.ImportKeyAsync(
            KeyFormat.Raw,
            hashedKey,
            new AesKeyAlgorithm("AES-GCM"),
            extractable: false,
            new[] { KeyUsage.Encrypt, KeyUsage.Decrypt });

        // 执行解密
        var plaintextBytes = await SubtleCrypto.DecryptAsync(
            new AesGcmParams { Iv = iv },
            cryptoKey,
            encryptedBytes);

        decryptedText = Encoding.UTF8.GetString(plaintextBytes);
    }
    catch (Exception ex)
    {
        decryptedText = $"解密失败:{ex.Message}";
    }
}

关键注意事项

  • 密钥长度适配:直接使用用户输入的字符串可能不符合加密算法的密钥长度要求(比如AES-256需要32字节),用SHA-256哈希可以将任意长度的输入转为标准32字节密钥材料,同时提升安全性。
  • IV的使用:每次加密必须使用全新的随机IV,IV不需要保密,和密文一起存储即可,这样能避免相同密钥加密相同内容时产生重复密文。
  • 密钥安全性:设置extractable: false可以防止密钥被意外导出,降低泄露风险。

内容的提问来源于stack exchange,提问作者Cal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 00:35:16