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

Dart中是否有类似crypto.subtle的工具?能否调用浏览器该API?

Dart中crypto.subtle替代方案与AES-CBC实现

一、访问浏览器原生crypto.subtle

在Dart Web环境中,可直接访问浏览器的crypto.subtle,你之前遇到的dart-html中Crypto.subtle不可访问的问题,大概率是用法有误。正确调用方式是通过window.crypto.subtle,示例代码如下:

import 'dart:html';
import 'dart:typed_data';

Future<Uint8List> cbcEncryptBrowser(Uint8List data, Uint8List iv, Uint8List key) async {
  // 导入密钥
  final importedKey = await window.crypto.subtle.importKey(
    'raw',
    key,
    {'name': 'AES-CBC'},
    false,
    ['encrypt', 'decrypt'],
  );
  // 加密数据
  final cipherBuffer = await window.crypto.subtle.encrypt(
    {'name': 'AES-CBC', 'iv': iv},
    importedKey,
    data,
  );
  return Uint8List.view(cipherBuffer);
}

注意:这段代码仅适用于Dart Web环境,无法在Flutter移动端或桌面端运行。

二、跨平台替代方案

1. cryptography包(推荐,API贴近web crypto)

你提到的cryptography包其实有直接对应AES-CBC的实现,以下是匹配你JS逻辑的代码:

import 'package:cryptography/cryptography.dart';
import 'dart:typed_data';

Future<Uint8List> cbcEncryptCryptography(Uint8List data, Uint8List iv, Uint8List key) async {
  final algorithm = AesCbc.with256bits(macAlgorithm: null); // 无需MAC,与JS逻辑对齐
  final secretKey = await algorithm.newSecretKeyFromBytes(key);
  final encrypted = await algorithm.encrypt(
    data,
    secretKey: secretKey,
    nonce: iv, // AES-CBC中nonce等价于IV
  );
  return encrypted.bytes;
}

该包支持Web、Flutter移动端、桌面端,跨平台兼容性优异。

2. pointycastle包

pointycastle是Dart生态老牌加密库,功能全面,定位与crypto.subtle类似(底层加密实现),但API风格更偏向传统密码库。对应实现如下:

import 'package:pointycastle/pointycastle.dart';
import 'dart:typed_data';

Uint8List cbcEncryptPointyCastle(Uint8List data, Uint8List iv, Uint8List key) {
  final cipher = CBCBlockCipher(AESEngine())
    ..init(
      true, // 加密模式
      ParametersWithIV(KeyParameter(key), iv),
    );
  // JS的crypto.subtle默认使用PKCS7补位,需手动实现
  final paddedData = _addPkcs7Padding(data, 16);
  final output = Uint8List(paddedData.length);
  var offset = 0;
  while (offset < paddedData.length) {
    offset += cipher.processBlock(paddedData, offset, output, offset);
  }
  return output;
}

// PKCS7补位实现
Uint8List _addPkcs7Padding(Uint8List data, int blockSize) {
  final paddingLength = blockSize - (data.length % blockSize);
  final padding = Uint8List(paddingLength)..fillRange(0, paddingLength, paddingLength);
  return Uint8List.fromList([...data, ...padding]);
}

三、总结

  • 仅Web环境:直接用window.crypto.subtle最贴合你的JS逻辑;
  • 跨平台需求:优先选择cryptography包,API简洁且贴近web crypto;pointycastle功能更全面,但需手动处理补位等细节。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 23:36:17