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

.NET Core 3.1 Ubuntu环境下SecureString加密解密异常解决方案问询

问题根因

你当前遇到的报错是因为System.Security.Cryptography.ProtectedData底层完全依赖Windows专属的DPAPI(数据保护接口),本身不支持Linux、macOS等非Windows平台,因此在Ubuntu环境下运行直接抛出平台不支持异常。

适配跨平台的实现方案

这里提供两种.NET Core 3.1下可在Ubuntu运行的SecureString加密解密实现方案:

方案1:使用官方跨平台Data Protection API(推荐)

这是微软官方提供的替代DPAPI的跨平台方案,支持全平台运行,默认会根据操作系统自动适配对应的加密逻辑,也支持自定义密钥存储、有效期等配置。

  1. 首先安装对应NuGet包:
Install-Package Microsoft.AspNetCore.DataProtection

非ASP.NET项目也可正常引用该包。
2. 配置DataProtection实例,对应原CurrentUser scope可以将密钥存在当前用户目录下:

using Microsoft.AspNetCore.DataProtection;
using System.Security;
using System.Text;

// 初始化DataProtectionProvider
var dataProtectionProvider = DataProtectionProvider.Create(
    new DirectoryInfo(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".your_app_name_secrets")),
    options => { options.SetApplicationName("your_app_unique_name"); });
var protector = dataProtectionProvider.CreateProtector("SecureStringEncryptionPurpose");
  1. 改写加密解密方法:
public static string EncryptString(SecureString input, IDataProtector protector)
{
    // 将SecureString转为明文字节数组
    var plainTextBytes = Encoding.Unicode.GetBytes(ToInsecureString(input));
    // 加密
    var encryptedBytes = protector.Protect(plainTextBytes);
    return Convert.ToBase64String(encryptedBytes);
}

public static SecureString DecryptString(string encryptedData, IDataProtector protector)
{
    try
    {
        var encryptedBytes = Convert.FromBase64String(encryptedData);
        var decryptedBytes = protector.Unprotect(encryptedBytes);
        var plainText = Encoding.Unicode.GetString(decryptedBytes);
        // 清除内存中的明文字节数组,避免敏感信息残留
        Array.Clear(decryptedBytes, 0, decryptedBytes.Length);
        return ToSecureString(plainText);
    }
    catch
    {
        return new SecureString();
    }
}

方案2:自定义AES对称加密实现

如果你不想引入ASP.NET相关依赖,可以自行实现AES对称加密,自行管理密钥和偏移量:

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

// 自行保管32位AES密钥和16位IV,生产环境不要硬编码,可通过环境变量、配置中心等方式读取
private static readonly byte[] AesKey = Encoding.UTF8.GetBytes("your_32_byte_aes_key_here_12345678");
private static readonly byte[] AesIV = Encoding.UTF8.GetBytes("your_16_byte_iv_");

public static string EncryptString(SecureString input)
{
    var plainTextBytes = Encoding.Unicode.GetBytes(ToInsecureString(input));
    using var aes = Aes.Create();
    aes.Key = AesKey;
    aes.IV = AesIV;
    using var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
    using var ms = new MemoryStream();
    using var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
    cs.Write(plainTextBytes, 0, plainTextBytes.Length);
    cs.FlushFinalBlock();
    var encryptedBytes = ms.ToArray();
    Array.Clear(plainTextBytes, 0, plainTextBytes.Length);
    return Convert.ToBase64String(encryptedBytes);
}

public static SecureString DecryptString(string encryptedData)
{
    try
    {
        var encryptedBytes = Convert.FromBase64String(encryptedData);
        using var aes = Aes.Create();
        aes.Key = AesKey;
        aes.IV = AesIV;
        using var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
        using var ms = new MemoryStream(encryptedBytes);
        using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
        using var reader = new StreamReader(cs, Encoding.Unicode);
        var plainText = reader.ReadToEnd();
        return ToSecureString(plainText);
    }
    catch
    {
        return new SecureString();
    }
}

注意事项

  • SecureString在非Windows平台下不会自动加密内存中的明文内容,仅能缩短明文在内存中的存活时间,无法实现Windows下的内存加密效果,如果你有更高的安全要求,建议在处理完明文后主动清空对应内存区域。
  • 自定义AES方案的密钥需要妥善保管,避免密钥泄露导致敏感数据被破解。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 23:36:07