Compare commits

...

6 commits

Author SHA1 Message Date
2dust
89ce7c23c9 Fix tun interface name in macos
Some checks are pending
release / build (Release) (push) Waiting to run
2024-11-26 15:32:35 +08:00
2dust
a5d99b1eb5 Improved Tun mode function in Linux version 2024-11-26 15:11:02 +08:00
2dust
800d193acb Bug fix 2024-11-26 14:39:33 +08:00
cryptochecktool
7a1d12be76
Update CoreHandler.cs (#6163)
将Desutils替换为Aesutils,提高安全性
2024-11-26 13:54:12 +08:00
cryptochecktool
1b9c95e801
Update OptionSettingViewModel.cs (#6162)
将Desutils替换为Aesutils,提升安全性。
2024-11-26 13:53:50 +08:00
cryptochecktool
9f44815470
Create AesUtils.cs (#6161)
新增AesUtils,替换掉DesUtils,提高安全性。
细节:
1.使用AES代替DES
2.正确使用IV调用方式
3.使用SHA256代替MD5进行密钥派生
4.使用PBKDF进行迭代生成密钥。
2024-11-26 13:52:37 +08:00
6 changed files with 132 additions and 17 deletions

View file

@ -0,0 +1,115 @@
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace ServiceLib.Common
{
public class AesUtils
{
private const int KeySize = 256; // AES-256
private const int IvSize = 16; // AES block size
private const int Iterations = 10000;
private static readonly byte[] Salt = Encoding.ASCII.GetBytes("saltysalt".PadRight(16, ' '));//google浏览器默认盐值
/// <summary>
/// Encrypt
/// </summary>
/// <param name="text">Plain text</param>
/// <param name="password">Password for key derivation</param>
/// <returns>Base64 encoded cipher text with IV</returns>
public static string Encrypt(string text, string password)
{
if (string.IsNullOrEmpty(text))
return string.Empty;
if (string.IsNullOrEmpty(password))
throw new ArgumentNullException("Password cannot be null.");
byte[] plaintext = Encoding.UTF8.GetBytes(text);
byte[] key = GetDefaultKey(password);
byte[] iv = GenerateIv();
using (Aes aes = Aes.Create())
{
aes.Key = key;
aes.IV = iv;
using (MemoryStream ms = new MemoryStream())
{
ms.Write(iv, 0, iv.Length);
using (CryptoStream cs = new CryptoStream(ms, aes.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(plaintext, 0, plaintext.Length);
cs.FlushFinalBlock();
}
byte[] cipherTextWithIv = ms.ToArray();
return Convert.ToBase64String(cipherTextWithIv);
}
}
}
/// <summary>
/// Decrypt
/// </summary>
/// <param name="cipherTextWithIv">Base64 encoded cipher text with IV</param>
/// <param name="password">Password for key derivation</param>
/// <returns>Plain text</returns>
public static string Decrypt(string cipherTextWithIv, string password)
{
if (string.IsNullOrEmpty(cipherTextWithIv))
return string.Empty;
if (string.IsNullOrEmpty(password))
throw new ArgumentNullException("Password cannot be null.");
byte[] cipherTextWithIvBytes = Convert.FromBase64String(cipherTextWithIv);
byte[] key = GetDefaultKey(password);
byte[] iv = new byte[IvSize];
Buffer.BlockCopy(cipherTextWithIvBytes, 0, iv, 0, IvSize);
byte[] cipherText = new byte[cipherTextWithIvBytes.Length - IvSize];
Buffer.BlockCopy(cipherTextWithIvBytes, IvSize, cipherText, 0, cipherText.Length - IvSize);
using (Aes aes = Aes.Create())
{
aes.Key = key;
aes.IV = iv;
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, aes.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherText, 0, cipherText.Length);
cs.FlushFinalBlock();
}
byte[] plainText = ms.ToArray();
return Encoding.UTF8.GetString(plainText);
}
}
}
private static byte[] GetDefaultKey(string password)
{
using (Rfc2898DeriveBytes pbkdf2 = new Rfc2898DeriveBytes(password, Salt, Iterations, HashAlgorithmName.SHA256))
{
return pbkdf2.GetBytes(KeySize / 8);
}
}
private static byte[] GenerateIv()
{
using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
{
byte[] iv = new byte[IvSize];
rng.GetBytes(iv);
return iv;
}
}
}
}

View file

@ -361,31 +361,28 @@ namespace ServiceLib.Handler
{
var cmdLine = $"{fileName.AppendQuotes()} {string.Format(coreInfo.Arguments, Utils.GetConfigPath(configPath).AppendQuotes())}";
//Prefer shell scripts
//Shell scripts
var shFilePath = Utils.GetBinPath("run_as_root.sh");
File.Delete(shFilePath);
var sb = new StringBuilder();
sb.AppendLine("#!/bin/sh");
sb.AppendLine(cmdLine);
await File.WriteAllTextAsync(shFilePath, sb.ToString());
await Utils.SetLinuxChmod(shFilePath);
//Replace command
var args = File.Exists(shFilePath) ? shFilePath : cmdLine;
if (_config.TunModeItem.LinuxSudoPwd.IsNotEmpty())
if (_config.TunModeItem.LinuxSudoPwd.IsNullOrEmpty())
{
proc.StartInfo.FileName = $"/bin/sudo";
proc.StartInfo.Arguments = $"-S {args}";
sb.AppendLine($"pkexec {cmdLine}");
}
else
{
proc.StartInfo.FileName = $"/bin/pkexec";
proc.StartInfo.Arguments = $"{args}";
sb.AppendLine($"sudo -S {cmdLine}");
proc.StartInfo.StandardInputEncoding = Encoding.UTF8;
proc.StartInfo.RedirectStandardInput = true;
}
proc.StartInfo.WorkingDirectory = null;
proc.StartInfo.StandardInputEncoding = Encoding.UTF8;
proc.StartInfo.RedirectStandardInput = true;
Logging.SaveLog(proc.StartInfo.Arguments);
await File.WriteAllTextAsync(shFilePath, sb.ToString());
await Utils.SetLinuxChmod(shFilePath);
proc.StartInfo.FileName = shFilePath;
proc.StartInfo.Arguments = "";
proc.StartInfo.WorkingDirectory = "";
Logging.SaveLog(shFilePath);
}
private async Task KillProcess(Process? proc)

View file

@ -548,6 +548,7 @@ namespace ServiceLib.Services.CoreConfig
}
var tunInbound = JsonUtils.Deserialize<Inbound4Sbox>(Utils.GetEmbedText(Global.TunSingboxInboundFileName)) ?? new Inbound4Sbox { };
tunInbound.interface_name = Utils.IsOSX()? $"utun{new Random().Next(99)}": "singbox_tun";
tunInbound.mtu = _config.TunModeItem.Mtu;
tunInbound.strict_route = _config.TunModeItem.StrictRoute;
tunInbound.stack = _config.TunModeItem.Stack;

View file

@ -379,6 +379,7 @@
</Grid.ColumnDefinitions>
<TextBlock
x:Name="tbAutoRun"
Grid.Row="1"
Grid.Column="0"
VerticalAlignment="Center"

View file

@ -172,6 +172,7 @@ namespace v2rayN.Desktop.Views
if (Utils.IsOSX())
{
tbAutoRun.IsVisible = false;
togAutoRun.IsVisible = false;
//TODO
}