C# 安全认证:牢不可破的保护

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

您的密码不仅仅是字符串:为什么 C# 中的认证需要特殊方法

\n\n

想象一下:您编写了一个完美的 C# 应用程序——拥有漂亮的界面、快速的查询和清晰的架构。但如果其中的认证存在漏洞,所有工作都将付诸东流。黑客不会破门而入——他们会配钥匙。在当今世界,C# 安全认证不是一种选择,而是代码的基本卫生。

\n\n

在本文中,我们将讨论的不仅仅是理论,而是实际的保护方法:从正确的密码哈希到 JWT 和 OAuth 的集成。您将了解为什么没有加盐的 SHA256 是邪恶的,如何避免暴力攻击的陷阱,以及当您的项目已经超出“初级”认证方法时该怎么做。让我们开始吧!

\n\n

安全的三大支柱:哈希、加盐和慢速算法

\n\n

新手最常见的反模式是以明文形式存储密码或使用普通的 MD5。即使您只有“一个学习项目”,这种习惯也会根深蒂固。C# 安全认证始于三条规则:

\n\n
    \n
  • 切勿以纯文本形式存储密码。即使在本地数据库中也不行。
  • \n
  • 使用盐值 (salt)——为每个用户生成一个随机字符串。
  • \n
  • 选择慢速算法——BCrypt、PBKDF2、Argon2。
  • \n
\n\n

为什么是“慢速”?因为黑客需要每秒尝试数十亿种组合。如果哈希过程需要 0.1 秒,攻击在经济上就变得不可行。

\n\n

以 BCrypt 为例,在 C# 中正确进行密码哈希

\n\n

BCrypt 是 .NET 开发人员的黄金标准。它会自动生成盐值并将其嵌入哈希中。您无需单独存储盐值。

\n\n

通过 NuGet 安装包:

\n
Install-Package BCrypt.Net-Next
\n\n

现在是一个用户注册示例:

\n\n
using BCrypt.Net;\n\npublic class AuthService\n{\n    public string HashPassword(string plainPassword)\n    {\n        // Work factor = 12 — 速度和安全性之间的最佳平衡\n        return BCrypt.HashPassword(plainPassword, workFactor: 12);\n    }\n\n    public bool VerifyPassword(string plainPassword, string hashedPassword)\n    {\n        return BCrypt.Verify(plainPassword, hashedPassword);\n    }\n}\n\n// 使用:\nvar auth = new AuthService();\nstring hash = auth.HashPassword("MyS3cur3P@ss!");\nbool isValid = auth.VerifyPassword("MyS3cur3P@ss!", hash); // true
\n\n

请注意:workFactor(成本因子)决定了将执行多少次哈希迭代。对于 2024 年来说,12 是一个很好的值。如果您的服务器性能强大,可以提高到 13-14。

\n\n

PBKDF2 — .NET 内置工具

\n\n

如果您不想使用第三方库,请使用 Rfc2898DeriveBytes——这是 .NET 中 PBKDF2 的内置实现。示例:

\n\n
using System.Security.Cryptography;\n\npublic static string HashWithPBKDF2(string password, byte[] salt, int iterations = 100_000)\n{\n    using var deriveBytes = new Rfc2898DeriveBytes(password, salt, iterations, HashAlgorithmName.SHA256);\n    byte[] hash = deriveBytes.GetBytes(32); // 32 字节 = 256 位\n    return Convert.ToBase64String(salt) + ":" + Convert.ToBase64String(hash);\n}\n\n// 生成盐值(16 字节)\nbyte[] salt = RandomNumberGenerator.GetBytes(16);\nstring result = HashWithPBKDF2("userPassword", salt);
\n\n

重要提示:不要使用少于 100,000 次迭代。现代 GPU 每秒可以轻松处理数百万个哈希值。

\n\n

JWT — 无会话的现代认证

\n\n

当您的 C# 应用程序扩展到微服务或 SPA(React、Vue)时,在服务器上存储会话变得不方便。这时 JSON Web Tokens (JWT) 就派上了用场——紧凑、自包含的访问令牌。

\n\n

使用 JWT 的 C# 安全认证 基于三个原则:

\n
    \n
  • 令牌

博客

书籍推荐