LumaTunnel
【WinUI】LumaTunnel 是一个面向个人多设备的 Windows 代理系统。客户端在本机提供 HTTP/HTTPS CONNECT 与 SOCKS5 TCP 代理,并通过一个受信任 TLS 证书保护的 WSS 会话,将多个 TCP 流复用到自建 Windows Server 节点。
关注
0
Fork
0
Star
0
using System.Security.Cryptography;
using System.Text;
using LumaTunnel.Client.Interface;
using XFEExtension.NetCore.WinUIHelper.Implements.Services;
namespace LumaTunnel.Client.Implements;
public sealed class SecretStore : GlobalServiceBase, ISecretStore
{
private readonly string _directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "LumaTunnel", "secrets");
public async Task SetAsync(string key, string value, CancellationToken cancellationToken = default)
{
Directory.CreateDirectory(_directory);
var plaintext = Encoding.UTF8.GetBytes(value);
var encrypted = ProtectedData.Protect(plaintext, Entropy(key), DataProtectionScope.CurrentUser);
await File.WriteAllBytesAsync(PathFor(key), encrypted, cancellationToken).ConfigureAwait(false);
CryptographicOperations.ZeroMemory(plaintext);
}
public async Task<string?> GetAsync(string key, CancellationToken cancellationToken = default)
{
var path = PathFor(key);
if (!File.Exists(path))
return null;
var encrypted = await File.ReadAllBytesAsync(path, cancellationToken).ConfigureAwait(false);
var plaintext = ProtectedData.Unprotect(encrypted, Entropy(key), DataProtectionScope.CurrentUser);
try { return Encoding.UTF8.GetString(plaintext); }
finally { CryptographicOperations.ZeroMemory(plaintext); }
}
public Task RemoveAsync(string key, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
var path = PathFor(key);
if (File.Exists(path)) File.Delete(path);
return Task.CompletedTask;
}
private string PathFor(string key) => Path.Combine(_directory, Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(key))) + ".secret");
private static byte[] Entropy(string key) => SHA256.HashData(Encoding.UTF8.GetBytes("LumaTunnel:" + key));
}
using System.Security.Cryptography;
using System.Text;
using LumaTunnel.Client.Interface;
using XFEExtension.NetCore.WinUIHelper.Implements.Services;
namespace LumaTunnel.Client.Implements;
public sealed class SecretStore : GlobalServiceBase, ISecretStore
{
private readonly string _directory = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "LumaTunnel", "secrets");
public async Task SetAsync(string key, string value, CancellationToken cancellationToken = default)
{
Directory.CreateDirectory(_directory);
var plaintext = Encoding.UTF8.GetBytes(value);
var encrypted = ProtectedData.Protect(plaintext, Entropy(key), DataProtectionScope.CurrentUser);
await File.WriteAllBytesAsync(PathFor(key), encrypted, cancellationToken).ConfigureAwait(false);
CryptographicOperations.ZeroMemory(plaintext);
}
public async Task<string?> GetAsync(string key, CancellationToken cancellationToken = default)
{
var path = PathFor(key);
if (!File.Exists(path))
return null;
var encrypted = await File.ReadAllBytesAsync(path, cancellationToken).ConfigureAwait(false);
var plaintext = ProtectedData.Unprotect(encrypted, Entropy(key), DataProtectionScope.CurrentUser);
try { return Encoding.UTF8.GetString(plaintext); }
finally { CryptographicOperations.ZeroMemory(plaintext); }
}
public Task RemoveAsync(string key, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
var path = PathFor(key);
if (File.Exists(path)) File.Delete(path);
return Task.CompletedTask;
}
private string PathFor(string key) => Path.Combine(_directory, Convert.ToHexString(SHA256.HashData(Encoding.UTF8.GetBytes(key))) + ".secret");
private static byte[] Entropy(string key) => SHA256.HashData(Encoding.UTF8.GetBytes("LumaTunnel:" + key));
}