diff --git a/OTP/Form1.Designer.cs b/OTP/Form1.Designer.cs
index 39e0eab..14bb647 100644
--- a/OTP/Form1.Designer.cs
+++ b/OTP/Form1.Designer.cs
@@ -46,6 +46,7 @@
this.listBox1.Name = "listBox1";
this.listBox1.Size = new System.Drawing.Size(473, 368);
this.listBox1.TabIndex = 0;
+ this.listBox1.SelectedIndexChanged += new System.EventHandler(this.listBox1_SelectedIndexChanged);
//
// label1
//
@@ -61,6 +62,7 @@
//
// button1
//
+ this.button1.Enabled = false;
this.button1.Location = new System.Drawing.Point(556, 294);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(85, 23);
@@ -171,6 +173,8 @@
this.Name = "Form1";
this.Text = "Main Window";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
+ this.Load += new System.EventHandler(this.Form1_Load);
+ this.VisibleChanged += new System.EventHandler(this.Form1_VisibleChanged);
this.ResumeLayout(false);
this.PerformLayout();
diff --git a/OTP/Form1.cs b/OTP/Form1.cs
index eacded1..d8864e3 100644
--- a/OTP/Form1.cs
+++ b/OTP/Form1.cs
@@ -8,6 +8,10 @@ using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using OtpNet;
+using System.IO;
+using System.Data.SQLite;
+using System.Reflection;
+using ZXing.QrCode.Internal;
namespace OTP
{
@@ -16,18 +20,28 @@ namespace OTP
private byte[] secretKey;
private Totp totp;
private Timer timer;
+ private string connectionString = "Data Source=key.db;Version=3;";
+ private string embeddedDatabaseResource = "OTP.empty_key.db";
+ private int runonce=0;
public Form1()
{
InitializeComponent();
-
- secretKey = Base32Encoding.ToBytes("JBSWY3DPEHPK3PXP"); // 示例的 base32 编码
- totp = new Totp(secretKey);
+ //button1.Enabled = false;
+ //secretKey = Base32Encoding.ToBytes("JBSWY3DPEHPK3PXP"); // 示例的 base32 编码
+ //totp = new Totp(secretKey);
timer = new Timer();
timer.Interval = 1000; // 设置计时器间隔为 1 秒
timer.Tick += Timer_Tick;
}
+ public class TitleInfo
+ {
+ public int Id { get; set; }
+ public string Title { get; set; }
+ public string SecretKey { get; set; }
+ }
+
private void Timer_Tick(object sender, EventArgs e)
{
@@ -55,16 +69,105 @@ namespace OTP
{
button1.Enabled = false; // 禁用生成按钮
button2.Enabled = true; // 启用复制按钮
- GenerateAndDisplayTotp(); // 生成并显示 TOTP 密码
-
- // 开始计时器
- timer.Start();
+ if (totp != null)
+ {
+ GenerateAndDisplayTotp(); // 生成并显示 TOTP 密码
+ timer.Start();// 开始计时器
+ }
}
private void Form1_Load(object sender, EventArgs e)
{
- button1.Enabled = true; // 在窗体加载时启用按钮
+ //button1.Enabled = true; // 在窗体加载时启用按钮
+ // 判断是否存在 key.db 数据库文件
+ if (!File.Exists("key.db"))
+ {
+ ExtractEmbeddedDatabase();
+ }
+
+
}
+ private void ExtractEmbeddedDatabase()
+ {
+ // 从嵌入的资源中复制数据库文件到同目录下
+ try
+ {
+ using (Stream resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(embeddedDatabaseResource))
+ {
+ using (FileStream fileStream = new FileStream("key.db", FileMode.Create))
+ {
+ resourceStream.CopyTo(fileStream);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"An error occurred while extracting embedded database: {ex.Message}");
+ }
+ }
+
+ private void LoadTitlesToListBox()
+ {
+ try
+ {
+ using (SQLiteConnection connection = new SQLiteConnection(connectionString))
+ {
+ connection.Open();
+
+ using (SQLiteCommand command = new SQLiteCommand("SELECT Id, Title, SecretKey FROM TotpData", connection))
+ {
+ using (SQLiteDataReader reader = command.ExecuteReader())
+ {
+ listBox1.Items.Clear(); // 清空现有数据
+ while (reader.Read())
+ {
+ int id = reader.GetInt32(0);
+ string title = reader.GetString(1);
+ string secretKey = reader.GetString(2);
+
+ TitleInfo titleInfo = new TitleInfo
+ {
+ Id = id,
+ Title = title,
+ SecretKey = secretKey
+ };
+
+ listBox1.Items.Add(titleInfo);
+ }
+ }
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"An error occurred while loading titles: {ex.Message}");
+ }
+ }
+
+ private void listBox1_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ if (listBox1.SelectedIndex >= 0) // Ensure an item is selected
+ {
+ TitleInfo selectedTitleInfo = listBox1.SelectedItem as TitleInfo;
+ if (selectedTitleInfo != null)
+ {
+ if (runonce == 0)
+ {
+ button1.Enabled = true;
+ runonce++;
+ }
+ secretKey = Base32Encoding.ToBytes(selectedTitleInfo.SecretKey);
+ totp = new Totp(secretKey);
+ //string totpCode = totp.ComputeTotp();
+ //label1.Text = totpCode;
+ }
+ else
+ {
+ MessageBox.Show("Selected item is not of the expected type.");
+ }
+ }
+ }
+
private void button2_Click(object sender, EventArgs e)
{
@@ -95,5 +198,21 @@ namespace OTP
// 如果用户选择 Yes,什么都不需要做,窗体会继续关闭
}
+ private void Form1_VisibleChanged(object sender, EventArgs e)
+ {
+ if (this.Visible) // 检查窗体是否可见
+ {
+ LoadTitlesToListBox();
+ runonce = 0;
+ label1.Text = "TOTP Code";
+ button1.Enabled = false;
+ button2.Enabled = false;
+ }
+ else
+ {
+ timer.Stop();
+ }
+ }
+
}
}
diff --git a/OTP/Form2.Designer.cs b/OTP/Form2.Designer.cs
index 0d664ac..615c1f1 100644
--- a/OTP/Form2.Designer.cs
+++ b/OTP/Form2.Designer.cs
@@ -81,6 +81,7 @@
this.button2.TabIndex = 2;
this.button2.Text = "Delete Record(s)";
this.button2.UseVisualStyleBackColor = true;
+ this.button2.Click += new System.EventHandler(this.button2_Click);
//
// button3
//
@@ -90,6 +91,7 @@
this.button3.TabIndex = 3;
this.button3.Text = "Save Changes";
this.button3.UseVisualStyleBackColor = true;
+ this.button3.Click += new System.EventHandler(this.button3_Click);
//
// button4
//
@@ -99,17 +101,20 @@
this.button4.TabIndex = 4;
this.button4.Text = "Discard Changes";
this.button4.UseVisualStyleBackColor = true;
+ this.button4.Click += new System.EventHandler(this.button4_Click);
//
// Form2
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(619, 367);
+ this.ControlBox = false;
this.Controls.Add(this.button4);
this.Controls.Add(this.button3);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.panel1);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Name = "Form2";
this.Text = "Data Manage";
this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form2_FormClosing);
diff --git a/OTP/Form2.cs b/OTP/Form2.cs
index 906afc9..ae275fb 100644
--- a/OTP/Form2.cs
+++ b/OTP/Form2.cs
@@ -8,19 +8,82 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
+using System.IO;
+using System.Security.Cryptography;
namespace OTP
{
public partial class Form2 : Form
{
private string connectionString = "Data Source=key.db;Version=3;";
+ private string backupPath = "key.db.bak"; // 备份数据库文件的路径
+ private string sourceFileHash = ""; // 原始数据库文件的哈希值
public Form2()
{
InitializeComponent();
InitializeDataGridView();
+ // 获取原始数据库文件的哈希值
+ sourceFileHash = CalculateSHA256Hash("key.db");
+ // 备份数据库文件并判断完整性
+ bool backupSuccessful = BackupDatabase();
+
+ if (!backupSuccessful)
+ {
+ // 备份创建失败,禁用按钮并提示用户
+ button1.Enabled = false;
+ button2.Enabled = false;
+ button3.Enabled = false;
+
+ MessageBox.Show("Backup of data failed, modification is prohibited.", "Backup Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
LoadData();
}
+ private bool BackupDatabase()
+ {
+ try
+ {
+ if (File.Exists("key.db"))
+ {
+ // 备份数据库文件
+ File.Copy("key.db", backupPath, true);
+
+ // 计算备份文件的哈希值
+ string backupFileHash = CalculateSHA256Hash(backupPath);
+
+ // 比较原始文件和备份文件的哈希值
+ if (sourceFileHash == backupFileHash)
+ {
+ return true; // 备份创建成功且完整性通过
+ }
+ else
+ {
+ return false; // 备份创建成功但完整性未通过
+ }
+ }
+ else
+ {
+ return false; // 原始文件不存在,备份创建失败
+ }
+ }
+ catch (Exception)
+ {
+ return false; // 备份创建失败
+ }
+ }
+ // 计算文件的SHA-256哈希值
+ private string CalculateSHA256Hash(string filePath)
+ {
+ using (SHA256 sha256 = SHA256.Create())
+ {
+ using (FileStream stream = File.OpenRead(filePath))
+ {
+ byte[] hashBytes = sha256.ComputeHash(stream);
+ return BitConverter.ToString(hashBytes).Replace("-", "").ToLower();
+ }
+ }
+ }
+
private void InitializeDataGridView()
{
@@ -34,19 +97,23 @@ namespace OTP
{
connection.Open();
- using (SQLiteCommand command = new SQLiteCommand("SELECT Title FROM TotpData", connection))
+ using (SQLiteCommand command = new SQLiteCommand("SELECT Id, Title FROM TotpData", connection))
{
using (SQLiteDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
- dataGridView1.Rows.Add(reader.GetString(0));
+ int id = reader.GetInt32(0);
+ string title = reader.GetString(1);
+ dataGridView1.Rows.Add(title);
+ dataGridView1.Rows[dataGridView1.Rows.Count - 1].Tag = id; // 将 Id 存储在行的 Tag 属性中
}
}
}
}
}
+
private void button1_Click(object sender, EventArgs e)
{
using (Form3 form3 = new Form3())
@@ -70,6 +137,89 @@ namespace OTP
}
}
+ private void button2_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ // 获取选中的行
+ foreach (DataGridViewRow selectedRow in dataGridView1.SelectedRows)
+ {
+ // 获取选中行的数据
+ int id = (int)selectedRow.Tag; // 从行的 Tag 属性获取 Id 值
+
+ // 执行删除数据库记录的操作
+ DeleteRecordFromDatabase(id);
+
+ // 从 DataGridView 中移除选中行
+ dataGridView1.Rows.Remove(selectedRow);
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"An error occurred while deleting the record: {ex.Message}");
+ }
+ }
+
+ private void DeleteRecordFromDatabase(int recordId)
+ {
+ try
+ {
+ using (SQLiteConnection connection = new SQLiteConnection(connectionString))
+ {
+ connection.Open();
+
+ using (SQLiteCommand command = new SQLiteCommand("DELETE FROM TotpData WHERE ID = @ID", connection))
+ {
+ command.Parameters.AddWithValue("@ID", recordId);
+ command.ExecuteNonQuery();
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"An error occurred while deleting the record: {ex.Message}");
+ }
+ }
+
+ private void button3_Click(object sender, EventArgs e)
+ {
+ // 删除备份文件
+ if (File.Exists(backupPath))
+ {
+ File.Delete(backupPath);
+ }
+
+ // 关闭当前的 Form2 实例,返回到 Form1
+ this.Close();
+ }
+
+ private void button4_Click(object sender, EventArgs e)
+ {
+ try
+ {
+ // 恢复备份文件
+ if (File.Exists(backupPath))
+ {
+ File.Copy(backupPath, "key.db", true);
+
+ // 删除备份文件
+ File.Delete(backupPath);
+
+ MessageBox.Show("The operation was successful.", "Undo Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ }
+ else
+ {
+ MessageBox.Show("No backup file found to undo changes.", "Undo Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show($"An error occurred while undoing changes: {ex.Message}", "Undo Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ }
+
+ // 关闭当前的 Form2 实例,返回到 Form1,不进行保存操作
+ this.Close();
+ }
}
}
diff --git a/OTP/OTP.csproj b/OTP/OTP.csproj
index ffdbe92..584983f 100644
--- a/OTP/OTP.csproj
+++ b/OTP/OTP.csproj
@@ -156,9 +156,8 @@
True
Resources.resx
-
- Always
-
+
+
SettingsSingleFileGenerator
diff --git a/OTP/empty_key.db b/OTP/empty_key.db
new file mode 100644
index 0000000..acb0eed
Binary files /dev/null and b/OTP/empty_key.db differ