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

.NET 6/7 .NET MAUI 无过时API的任意长度密码字符串加解密实现

.NET 6/7 兼容 MAUI 的无过时警告加密解密实现

以下实现完全封装加盐、PBKDF2密钥派生、认证加密全流程,编译无OBSOLETE弃用警告,支持最低4位长度密码,输出密文为Base64格式,可直接用于存储、传输,调用时无需额外配置安全参数。

首先引入所需命名空间:

using System.Security.Cryptography;
using System.Text;

完整实现代码:

public static class CryptoHelper
{
    // 固定安全参数,无需外部配置
    private const int SaltSize = 16;
    private const int KeySize = 32;
    private const int NonceSize = 12;
    private const int TagSize = 16;
    private const int Pbkdf2Iterations = 100000;
    private const int MinPasswordLength = 4;

    public static string Encrypt(string plainText, string password)
    {
        if (string.IsNullOrWhiteSpace(plainText))
            throw new ArgumentNullException(nameof(plainText));
        if (string.IsNullOrWhiteSpace(password) || password.Length < MinPasswordLength)
            throw new ArgumentException($"密码长度不得低于{MinPasswordLength}位", nameof(password));

        // 生成密码学安全的随机盐与Nonce
        byte[] salt = RandomNumberGenerator.GetBytes(SaltSize);
        byte[] nonce = RandomNumberGenerator.GetBytes(NonceSize);

        // PBKDF2派生AES密钥,使用SHA256哈希,无过时API调用
        using Rfc2898DeriveBytes keyDeriver = new Rfc2898DeriveBytes(password, salt, Pbkdf2Iterations, HashAlgorithmName.SHA256);
        byte[] encryptionKey = keyDeriver.GetBytes(KeySize);

        // AES-GCM认证加密
        using AesGcm aes = new AesGcm(encryptionKey, TagSize);
        byte[] plainBytes = Encoding.UTF8.GetBytes(plainText);
        byte[] cipherBytes = new byte[plainBytes.Length];
        byte[] authTag = new byte[TagSize];
        aes.Encrypt(nonce, plainBytes, cipherBytes, authTag);

        // 拼接密文结构:盐 + Nonce + 认证标签 + 实际密文
        byte[] result = new byte[SaltSize + NonceSize + TagSize + cipherBytes.Length];
        Buffer.BlockCopy(salt, 0, result, 0, SaltSize);
        Buffer.BlockCopy(nonce, 0, result, SaltSize, NonceSize);
        Buffer.BlockCopy(authTag, 0, result, SaltSize + NonceSize, TagSize);
        Buffer.BlockCopy(cipherBytes, 0, result, SaltSize + NonceSize + TagSize, cipherBytes.Length);

        return Convert.ToBase64String(result);
    }

    public static string Decrypt(string cipherText, string password)
    {
        if (string.IsNullOrWhiteSpace(cipherText))
            throw new ArgumentNullException(nameof(cipherText));
        if (string.IsNullOrWhiteSpace(password) || password.Length < MinPasswordLength)
            throw new ArgumentException($"密码长度不得低于{MinPasswordLength}位", nameof(password));

        byte[] fullCipherData;
        try
        {
            fullCipherData = Convert.FromBase64String(cipherText);
        }
        catch (FormatException)
        {
            throw new InvalidDataException("密文格式无效");
        }

        if (fullCipherData.Length < SaltSize + NonceSize + TagSize)
            throw new InvalidDataException("密文格式无效");

        // 拆分密文各组成部分
        byte[] salt = new byte[SaltSize];
        byte[] nonce = new byte[NonceSize];
        byte[] authTag = new byte[TagSize];
        byte[] cipherBytes = new byte[fullCipherData.Length - SaltSize - NonceSize - TagSize];

        Buffer.BlockCopy(fullCipherData, 0, salt, 0, SaltSize);
        Buffer.BlockCopy(fullCipherData, SaltSize, nonce, 0, NonceSize);
        Buffer.BlockCopy(fullCipherData, SaltSize + NonceSize, authTag, 0, TagSize);
        Buffer.BlockCopy(fullCipherData, SaltSize + NonceSize + TagSize, cipherBytes, 0, cipherBytes.Length);

        // 派生相同密钥解密
        using Rfc2898DeriveBytes keyDeriver = new Rfc2898DeriveBytes(password, salt, Pbkdf2Iterations, HashAlgorithmName.SHA256);
        byte[] encryptionKey = keyDeriver.GetBytes(KeySize);

        using AesGcm aes = new AesGcm(encryptionKey, TagSize);
        byte[] plainBytes = new byte[cipherBytes.Length];

        try
        {
            aes.Decrypt(nonce, cipherBytes, authTag, plainBytes);
        }
        catch (CryptographicException)
        {
            throw new InvalidDataException("密码错误或密文已被篡改");
        }

        return Encoding.UTF8.GetString(plainBytes);
    }
}

内置安全机制说明

  • 随机加盐:每次加密自动生成16字节密码学安全随机盐,相同密码加密相同明文也会得到完全不同的密文,阻断彩虹表攻击路径
  • PBKDF2密钥派生:采用SHA256哈希算法、10万次迭代从用户密码派生256位AES密钥,避免短PIN类弱密码直接作为加密密钥的风险,迭代次数在MAUI支持的全平台设备上运行无明显性能卡顿
  • 认证加密:使用AES-GCM加密模式,自带密文完整性校验,密码错误、密文被篡改时会直接抛出异常,不会输出被篡改的无效明文
  • 所有随机值均通过RandomNumberGenerator生成,为密码学安全级随机源,不存在可预测风险

注:4位PIN类密码本身熵值较低,仅适合用于本地非高敏感数据加密场景,不要用该方案存储高敏感的金融、身份类数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 03:06:19