Compare commits

..

No commits in common. "01d35456bde3be7ecfd8b1ea7d0916fe1b764312" and "89ce7c23c9791fc343844807083c3fff5ec21ab0" have entirely different histories.

2 changed files with 65 additions and 50 deletions

View file

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

View file

@ -439,7 +439,8 @@ namespace ServiceLib.ViewModels
} }
else if (Utils.IsOSX()) else if (Utils.IsOSX())
{ {
return _config.TunModeItem.LinuxSudoPwd.IsNotEmpty(); //TODO
return false;
} }
return false; return false;
} }