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

MAUI/C#应用中SSH凭据的安全存储方案咨询

MAUI/C# 中SSH密码的安全存储方案

一、加密后存储为字符串/字节数组(基于Preferences扩展)

完全可以对密码加密后以字符串或字节数组形式存储,核心是利用可靠的加密算法结合设备级别的密钥管理,避免密码明文暴露。

实现示例

// 加密方法(基于AES对称加密)
private string EncryptPassword(string password, string encryptionKey)
{
    using var aes = Aes.Create();
    aes.Key = Encoding.UTF8.GetBytes(encryptionKey.PadRight(32).Substring(0,32)); // 适配AES密钥长度要求
    aes.IV = new byte[16]; // 生产环境建议生成随机IV并与密文一起存储,此处为简化示例
    
    var encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
    using var ms = new MemoryStream();
    using var cs = new CryptoStream(ms, encryptor, CryptoStreamMode.Write);
    using var sw = new StreamWriter(cs);
    sw.Write(password);

    // 将IV与密文拼接后编码为Base64字符串
    return Convert.ToBase64String(aes.IV.Concat(ms.ToArray()).ToArray());
}

// 解密方法
private string DecryptPassword(string encryptedPassword, string encryptionKey)
{
    var fullBytes = Convert.FromBase64String(encryptedPassword);
    var iv = fullBytes.Take(16).ToArray();
    var cipherBytes = fullBytes.Skip(16).ToArray();

    using var aes = Aes.Create();
    aes.Key = Encoding.UTF8.GetBytes(encryptionKey.PadRight(32).Substring(0,32));
    aes.IV = iv;
    var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

    using var ms = new MemoryStream(cipherBytes);
    using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
    using var sr = new StreamReader(cs);
    return sr.ReadToEnd();
}

// 存储加密后的密码
var deviceKey = GetDeviceSpecificKey(); // 需实现获取设备唯一密钥(如基于平台安全存储生成)
var encryptedPwd = EncryptPassword(entryPassword.Text, deviceKey);
Preferences.Default.Set("encryptedPassword", encryptedPwd);

关键提示:GetDeviceSpecificKey()建议依托平台原生安全机制实现,比如Android的KeyStore、iOS的Keychain,避免硬编码密钥导致泄露。

二、序列化ConnectionInfo为JSON文件(需加密整个文件)

可以序列化ConnectionInfo对象为JSON,但绝对不能明文存储,必须对整个JSON内容加密后再写入文件。

实现步骤

  1. 定义ConnectionInfo类:
public class ConnectionInfo
{
    public string Hostname { get; set; }
    public int Port { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
}
  1. 序列化+加密存储:
// 构造对象并序列化
var connectionInfo = new ConnectionInfo
{
    Hostname = entryHostname.Text,
    Port = int.Parse(entryPort.Text),
    Username = entryUsername.Text,
    Password = entryPassword.Text
};
var jsonContent = JsonSerializer.Serialize(connectionInfo);

// 加密后写入文件
var deviceKey = GetDeviceSpecificKey();
var encryptedJson = EncryptPassword(jsonContent, deviceKey);
var savePath = Path.Combine(FileSystem.AppDataDirectory, "ssh_connection.json");
File.WriteAllText(savePath, encryptedJson);

// 读取时解密还原
var encryptedContent = File.ReadAllText(savePath);
var decryptedJson = DecryptPassword(encryptedContent, deviceKey);
var restoredInfo = JsonSerializer.Deserialize<ConnectionInfo>(decryptedJson);

三、优先推荐:MAUI SecureStorage

MAUI自带的SecureStorage是跨平台安全存储的最优解,底层直接对接各平台原生安全组件:

  • Android:依托KeyStore管理密钥,加密后存储数据
  • iOS:使用Keychain存储
  • Windows:利用Credential Locker

代码示例

// 存储密码
await SecureStorage.Default.SetAsync("ssh_password", entryPassword.Text);

// 获取密码
var storedPassword = await SecureStorage.Default.GetAsync("ssh_password");

该方案无需自己实现加密逻辑,避免手动加密可能出现的漏洞,同时跨平台兼容性拉满。

四、主流应用的实现参考

1. JuiceSSH

JuiceSSH(Android平台)将SSH密码通过AES加密后存储在本地数据库,加密密钥由Android KeyStore生成管理,密钥不会暴露给应用层,确保密码无法被明文提取。

2. Raspicast

Raspicast的密码加密逻辑(翻译自其Java实现):

  • 采用AES/CBC/PKCS5Padding加密算法
  • 基于设备Android ID+固定盐值生成256位AES密钥
  • 生成随机16字节IV,与密文拼接后编码为Base64字符串存储
  • 解密时拆分IV与密文,用相同密钥还原密码

总结

优先选择MAUI SecureStorage,这是最省心且安全的跨平台方案;若需自定义存储格式,可选择加密后用Preferences存储,或加密整个JSON文件;避免自行实现底层加密逻辑,尽量依托平台原生安全机制。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 17:03:27