功能更新

This commit is contained in:
GG Z
2026-02-23 11:21:51 +08:00
parent 3650f8550e
commit 6beb8b5be9
24 changed files with 694 additions and 1975 deletions

View File

@@ -3,6 +3,7 @@ using System.IO;
using System.Security.Cryptography;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using iNKORE.UI.WPF.Modern;
@@ -174,7 +175,7 @@ namespace KeyGen
Message.Text = ($"导入文件私钥完成");
}
}
private void Button_ToggleTheme_Click(object sender, RoutedEventArgs e)
private void ToggleTheme_Click(object sender, RoutedEventArgs e)
{
if (ThemeManager.Current.ApplicationTheme == ApplicationTheme.Dark)
{
@@ -185,5 +186,61 @@ namespace KeyGen
ThemeManager.Current.ApplicationTheme = ApplicationTheme.Dark;
}
}
/// <summary>
/// 生成通用的 6 位应急码
/// </summary>
/// <param name="durationTag">"1D", "7D", 或 "30D"</param>
public static string GenerateGlobalOTP(string durationTag, string salt)
{
string secret = salt + durationTag;
// 计算天数步长
long unixTime = (long)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds;
long step = unixTime / 86400;
byte[] secretBytes = Encoding.UTF8.GetBytes(secret);
// 字符表必须严格一致
string charset = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
// 步长转 8 字节大端
byte[] stepBytes = BitConverter.GetBytes(step);
if (BitConverter.IsLittleEndian) Array.Reverse(stepBytes);
byte[] msg = new byte[8];
Array.Copy(stepBytes, 0, msg, 8 - stepBytes.Length, stepBytes.Length);
using (var hmac = new HMACSHA1(Encoding.UTF8.GetBytes(secret)))
{
byte[] hash = hmac.ComputeHash(msg);
int offset = hash[hash.Length - 1] & 0xf;
uint binary = (uint)(((hash[offset] & 0x7f) << 24) | ((hash[offset + 1] & 0xff) << 16) | ((hash[offset + 2] & 0xff) << 8) | (hash[offset + 3] & 0xff));
string code = "";
for (int i = 0; i < 6; i++)
{
code += charset[(int)(binary % (uint)charset.Length)];
binary /= (uint)charset.Length;
}
return code;
}
}
private void DynamicLicenseClick(object sender, RoutedEventArgs e)
{
if (DynamicDurationComboBox.SelectedItem is not ComboBoxItem selectedItem)
{
Message.Text = ("请选择授权时长");
return;
}
if (string.IsNullOrEmpty(SaltTextBox.Text))
{
Message.Text = ("请设置Salt值");
return;
}
string durationTag = selectedItem.Tag.ToString();
string salt = SaltTextBox.Text.Trim();
string globalOTP = GenerateGlobalOTP(durationTag, salt);
DynamicLicenseTextBox.Text = globalOTP;
Clipboard.SetText(globalOTP);
Message.Text = "动态应急码已复制!";
}
}
}