.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
相关产品推荐
相关产品推荐

