安全性 API 的最佳做法

为了帮助开发安全软件,建议在开发应用程序时使用以下最佳做法。 有关详细信息,请参阅 Microsoft 安全开发生命周期

安全开发生命周期

安全开发生命周期 (SDL) 是一个流程,它使一系列以安全为中心的活动和可交付结果与软件开发的每个阶段保持一致。 这些活动和可交付结果包括:

  • 开发威胁模型
  • 使用代码扫描工具
  • 执行代码评审和安全测试

有关 SDL 的详细信息,请参阅 Microsoft 安全开发生命周期

威胁模型

执行威胁模型分析可帮助您发现代码中潜在的攻击点。 有关威胁模型分析的详细信息,请参阅 Howard、Michael 和 LeBlanc、David [2003]、Writing Secure Code、2d ed.、ISBN 0-7356-1722-8、Microsoft Press、Redmond、Washington。 (此资源或许不提供某些语言版本,或在某些国家或地区可能不可用。)

服务包和安全更新

生成和测试环应与目标用户群的服务包和安全更新水平保持一致。 建议为任何属于生成和测试环境的Microsoft平台或应用程序安装最新的 Service Pack 和安全更新,并鼓励用户为完成的应用程序环境执行相同的操作。 有关 Service Pack 和安全更新的详细信息,请参阅 Update WindowsMicrosoft 安全

授权

您应创建需要最低特权的应用程序。 使用尽可能少的权限可降低恶意代码损害计算机系统的风险。 有关以最低可能的权限级别运行代码的详细信息,请参阅使用特殊特权运行

加密最佳做法

在Windows应用程序中实现加密时:

  • 对于所有新的开发工作,请使用 加密 API: 下一代 (CNG)。 仅保留 CryptoAPI 以实现向后兼容性。
  • 为加密敏捷性而设计,并为后量子时代做好规划。 不要在整个代码中分散硬编码算法标识符或密钥大小, 隔离这些标识符,以便无需重写即可交换算法。 该平台正迁移至 NIST 后量子标准:使用 ML-KEM(FIPS 203)进行密钥建立,使用 ML-DSA(FIPS 204)进行签名,因此现在应优先采用敏捷设计——尤其是对于需要长期保密的数据,以抵御“现在收集、将来解密”攻击。
  • 首选经过身份验证的加密(AEAD)。 使用 AES-GCM,这样加密还能检测篡改。 如果必须使用未经身份验证的模式(如 CBC),请将其与单独的完整性检查(encrypt-then-MAC)配对 - 仅保密性就不能防止修改。
  • 在 AES-GCM 中,切勿对同一密钥重复使用 nonce(IV)。 GCM 中的 Nonce 重用是灾难性的:它可以公开身份验证密钥并启用消息伪造。 为每个加密操作生成唯一的 nonce — 例如,递增计数器或新鲜的随机 96 位值。
  • 切勿使用 ECB 块密码模式。 ECB 会独立加密各个块,从而泄露明文数据中的模式。
  • 从不对源代码中的加密密钥进行硬编码 。 将 DPAPI 用于本地密钥保护,或将 CNG 密钥存储提供程序 用于持久性密钥。
  • 使用完毕后从内存中清除机密。 使用 SecureZeroMemory 覆盖密钥材料、密码和其他敏感缓冲区。 与 memset 不同,它不会被编译器优化掉。
  • 将 256 位的密钥长度用于 AES,2048+ 位用于 RSA(首选 3072+ 位),对于 ECDSA,请使用 256 位以上的密钥长度。
  • 使用 SHA-256 或更强 的哈希。 不要将 MD5 或 SHA-1 用于安全目的。
  • 始终检查加密函数的返回值 。 无提示失败的加密调用可能会使数据存储在纯文本中。
  • 使用 BCryptGenRandom (CNG) 生成随机数 , 而不是rand()或其他非加密 PRNG。 传递 BCRYPT_USE_SYSTEM_PREFERRED_RNG 以使用系统首选生成器,而无需管理算法句柄。

更多信息

有关最佳实践的详细信息,请参阅以下主题。

主题 说明
使用特殊权限运行
讨论特权的安全影响。
避免缓冲区溢出
提供有关避免缓冲区溢出的信息。
控制流防护 (CFG)
讨论内存损坏漏洞。
创建 DACL
演示如何使用安全描述符定义语言 (SDDL) 创建自由访问控制列表 (DACL)。
处理密码
讨论使用密码的安全影响。
Dynamic 访问控制开发人员扩展性
新动态访问控制解决方案的一些开发人员扩展点的基本方向。