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

如何在Dart/Python中模仿char[]存储密码以防范内存dump攻击?

在Dart或Python中覆写内存规避密码内存dump风险的方法

Java里用char[]存储密码的核心优势是可以手动覆写内存,避免密码数据长时间留存。而Python和Dart的普通列表是对象列表,无法直接操作底层内存,但我们可以通过专门的字节类型来实现类似的内存覆写效果:

Python 中的解决方案

  • 优先使用bytearray:bytearray是可变的字节序列,直接对应底层内存区域。存储密码时先将输入转成字节编码的bytearray,使用完成后用全零字节覆盖整个数组:
# 获取用户输入并转为bytearray
password_input = input("请输入密码: ").encode('utf-8')
pwd_bytes = bytearray(password_input)

# 在这里执行密码验证、加密等操作
# ...

# 使用完毕立即覆写内存
pwd_bytes[:] = b'\x00' * len(pwd_bytes)
  • 借助ctypes底层操作(慎用):如果需要更极致的内存控制,可以通过ctypes模块获取字节对象的内存地址,直接写入零值。但这种方法依赖Python的具体实现,跨平台兼容性差,仅在特殊场景使用。
  • 全程避免字符串存储:Python的字符串是不可变的,一旦创建就无法修改,会在内存中留存直到垃圾回收(GC)触发。因此处理密码的全流程尽量用字节类型,不要转成字符串。

Dart 中的解决方案

  • 使用Uint8List可变字节列表:Uint8List属于Dart的TypedData类型,直接操作连续的底层字节内存。将密码字符串转成UTF-8字节存入后,使用完毕遍历列表写入零值覆写:
import 'dart:convert';
import 'dart:typed_data';

void handlePassword() {
  String userInput = "用户输入的密码";
  Uint8List pwdBytes = utf8.encode(userInput) as Uint8List;

  // 执行密码验证等业务操作
  // ...

  // 立即覆写内存
  for (int i = 0; i < pwdBytes.length; i++) {
    pwdBytes[i] = 0;
  }
}
  • 拒绝用String长期存储密码:Dart的String是不可变对象,创建后无法修改内容,密码会以原始形式留在内存中直到GC回收。因此处理密码时要尽量用Uint8List这类可变字节类型,减少不可变副本的留存。

通用注意事项

  • 即时清理:密码使用完成后必须立即执行覆写操作,不要依赖GC自动回收——GC的触发时机不确定,可能导致密码在内存中留存数分钟甚至更久。
  • 避免额外副本:不要将密码赋值给其他变量、存入缓存或写入日志,防止密码数据在内存中产生多个副本难以清理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 17:20:34