# 55屆公開第五題 ## 題目要求: (1) 設計畫面,包含系統標題、文字標籤、兩個 TextBox 控制項:txtUsername 和 txtPassword,分別用於輸入使用者名稱和密碼,密碼顯示為 * 符號。 (2) 新增兩個 Button 控制項:btnRegister、btnCancel,用於觸發註冊事件與取消 輸入的帳密內容。 (3) 按下「註冊」按鈕時,將所輸入的帳號及密碼存入文字檔。 (4) 密碼加密須使用 SHA256 進行密碼 HASH 加密。 檔案結構為使用者名稱和密碼,以 | 分隔,密碼儲存為 HASH 值。 範例:user1|ed02457b5c41d964dbd2f2a609d63fe1bb7528dbe55e1abf5b52c249cd735797 user2|9834876dcfb05cb167a5c24953eba58c4ac89b1adf57f28f2f9d09af107ee8f0 (5) 若成功儲存檔案,則顯示「註冊成功!」訊息。 ## 我的作法 ### 介面 依照執行結果參考畫面拉出一模一樣的介面,密碼遮擋我是在PasswordChar將符號改成* ![image](https://hackmd.io/_uploads/HJL8Tz7Kyx.png) ### 取消按鈕 這最簡單,直接寫一個close就好 ```csharp private void btnCancel_Click(object sender, EventArgs e) { Close(); } ``` ### 註冊 把用戶輸入的字符改成要輸入進txt的格式(同時加密),然後寫入user.txt之後顯示註冊成功 ```csharp private void btnRegister_Click(object sender, EventArgs e) { string user_and_pwd = txtUsername.Text + "||" + BitConverter.ToString(SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(txtPassword.Text))).Replace("-", "")+ "\r\n"; using (StreamWriter sw = new StreamWriter("user.txt", true)) { sw.WriteLine(user_and_pwd); } MessageBox.Show("註冊成功!","成功訊息",MessageBoxButtons.OK, MessageBoxIcon.Information); } ``` #### 這串是什麼 這串看起來很複雜,他長這樣 ```csharp BitConverter.ToString(SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(txtPassword.Text))).Replace("-", "")+ "\r\n" ``` [這裡學姊有寫一個筆記](https://hackmd.io/@anna0212/S13dSfQK1g) 簡單來說就是 先轉換字串成位元組 ```csharp byte[] passwordBytes = Encoding.UTF8.GetBytes(password); ``` 然後計算 SHA-256 雜湊 ```csharp using (SHA256 sha256 = SHA256.Create()) { byte[] hashBytes = sha256.ComputeHash(passwordBytes); } ``` 轉成16進制 ```csharp string hexHash = BitConverter.ToString(hashBytes); ``` 移除- ```csharp= string finalHash = hexHash.Replace("-", ""); ``` 就轉換好了 ### 完整程式碼 不要直接使用,下面會有可以下載的檔案 ```csharp= using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO; using System.Linq; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using static System.Net.Mime.MediaTypeNames; namespace CSA05 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void textBox1_TextChanged(object sender, EventArgs e) { } private void btnCancel_Click(object sender, EventArgs e) { Close(); } private void btnRegister_Click(object sender, EventArgs e) { string user_and_pwd = txtUsername.Text + "||" + BitConverter.ToString(SHA256.Create().ComputeHash(Encoding.UTF8.GetBytes(txtPassword.Text))).Replace("-", "")+ "\r\n"; using (StreamWriter sw = new StreamWriter("user.txt", true)) { sw.WriteLine(user_and_pwd); } MessageBox.Show("註冊成功!","成功訊息",MessageBoxButtons.OK, MessageBoxIcon.Information); } } } ``` ### 運行結果 ![image](https://hackmd.io/_uploads/BkgWJ7Xtyx.png) ![image](https://hackmd.io/_uploads/HyvWJ7mYJe.png) ![image](https://hackmd.io/_uploads/r1bmyXQtyl.png) ## 完整程式碼檔案 我放onedrive了(感謝教育局的15G空間) [點我下載](https://o365oid-my.sharepoint.com/:u:/g/personal/zack1121_ntpc_ms_edu_tw/EQ4q974zj0VIqx-dFR_fN_4BLDySGP34ZxV5Kan6c5dmsA?e=SRigxD) 結構應該長這樣: ``` CSA05: │ CSA05.sln │ └─CSA05 │ App.config │ Program.cs │ CSA05.csproj │ Form1.Designer.cs │ Form1.resx │ Form1.cs │ ├─Properties │ AssemblyInfo.cs │ Resources.resx │ Resources.Designer.cs │ Settings.settings │ Settings.Designer.cs │ ├─bin │ └─Debug │ CSA05.exe.config │ user.txt │ CSA05.exe │ CSA05.pdb │ └─obj └─Debug │ .NETFramework,Version=v4.7.2.AssemblyAttributes.cs │ DesignTimeResolveAssemblyReferencesInput.cache │ CSA05.csproj.AssemblyReference.cache │ CSA05.Form1.resources │ CSA05.Properties.Resources.resources │ CSA05.csproj.CoreCompileInputs.cache │ CSA05.exe │ CSA05.pdb │ CSA05.csproj.FileListAbsolute.txt │ CSA05.csproj.GenerateResource.cache │ DesignTimeResolveAssemblyReferences.cache │ └─TempPE ```