2015-01-08 33 views
2

我正在編寫C#應用程序來管理密碼。目前,我的數據庫是.txt文件,但我想創建幾種方式來存儲它。文件是.mdf文件的一個好辦法嗎? 我知道如何管理.mdf文件中的sql數據庫,但我不知道如何另存爲用戶選擇的位置或如何重新加載它以編程。保存並從文件加載sql數據庫

Ofcourse它可以是任何不同的文件類型。我尋找最安全的方式來做到這一點。將來我會創建asp.net應用程序和Xamarin android應用程序來在少數平臺上管理這個。

@編輯 我會盡量多解釋一次。選中此項:

用戶執行程序。可以選擇創建新的數據庫或加載現有的數據庫。 在創建模式下,用戶可以設置數據庫的類型。現在我只有一個,它是txt。 我想知道其他,f.e. .mdf,但我不知道如何將.mdf文件保存在用戶選擇的位置。任何其他關於可能的擴展和如何保護它的建議,我們感激不盡。

我要存儲它如下:

登錄|密碼| linkForWebsite |

Ofcourse我會散列一切,所以如果any1打開.txt文件,他不會看到任何東西。

散列此字符串的建議(不是md5,它必須是2種方式)也歡迎。

+0

*** *** SQL只是*結構化查詢語言* - 一個由許多數據庫系統中使用的語言,但不是數據庫產品ct ...很多東西都是特定於供應商的 - 所以我們真的需要知道您使用的數據庫系統**(以及哪個版本)(請相應地更新標籤)。 –

+0

我建議您擁有自己的文件與某種加密/散列。 – danish

+0

marc_s - 是的,我知道。我現在沒有任何系統,只是問是否有任何系統可以用於這種應用程序以及如何使用它。 丹尼斯 - 我也爲此而努力。 – titol

回答

2

基於以上我的評論,在這裏你可以做什麼

您的應用程序將從List<SiteDetail>讀取其中站點詳細信息是

[Serializable()] 
public class SiteDetail 
{ 
    public string Login{get; set;} 
    public string Password{get; set;} 
    public string Url{get; set;} 
} 

那麼當你想存儲的數據(保存),你請執行下列操作

public void Save(string filePath,List<SiteDetail> data) 
{ 
    Stream stream= File.Create(filePath); 
    BinaryFormatter serializer = new BinaryFormatter(); 
    serializer.Serialize(stream, data); 
    stream.Close(); 
} 

,當你要檢索的數據(讀),你就以下

public List<SiteDetail> Read(string filePath) 
    { 
     if (File.Exists(FileName)) 
     { 
      Stream stream= File.OpenRead(filePath); 
      BinaryFormatter deserializer = new BinaryFormatter(); 
      var details= (List<SiteDetail>)deserializer.Deserialize(stream); 
      stream.Close(); 
      return details; 
     } 
     return null; // file not exists 
    } 

用於加密數據檢查本文Encrypting and Decrypting Data

如果您還有任何疑問,請繼續

編輯

如你所提到的保存有關數據的元信息評論,你可以創建另一個名爲meta.dat的文件(將存儲另一個類[版本,文化,....等]),或者你可以輕鬆地添加被叫SiteVersion另一個類如下

[Serializable()] 
public class SiteVersion : SiteDetail // inherited from SiteDetail to store backup 
{ 
    public int Version{get; set;} 
    public string Culture{get; set;} 
    public DateTime CreatedOn{get; set;} 
} 

,並在您SiteDetail類,你可以添加List<SiteVersion>屬性,你可以填寫以往任何時候的任何變化作出時,這樣你可以在你的文件的細節存儲與其歷史版本也

[Serializable()] 
public class SiteDetail 
{ 
    public string Login{get; set;} 
    public string Password{get; set;} 
    public string Url {get;set;} 

    public List<SiteVersion> Versions {get; set;} 
} 

希望這將有助於你

+0

好!我會查一下。現在我有一個問題:字符串文件路徑,我應該使用哪個擴展名?或者,也許它應該是隨機擴展? – titol

+0

@titol,它可以是任何擴展名,選擇一個描述性的擴展名,例如wsld(web安全登錄數據) – Monah

+0

@titol,如果你在應用中使用了鏈接中描述的加密,這個文件中的數據不會是如果有人打開文件並在其中播放並再次保存,應用程序無法再讀取它,但只要用戶對您的應用程序感興趣,就不會發生這種情況 – Monah

0

如果你想節省.txt文件數據庫,你應該如下:

  1. 創建特定的路徑上的文本文件,如(C:\ bkpDB.txt)

  2. 權點擊開始(數據庫名稱) - >選擇(「任務」) - >選擇(「導出數據」) - >爲「歡迎頁面」選擇「下一步」 - >頁面「選擇數據源」:不要改變任何內容轉到下一頁 - >

  3. Page「Choo選擇目的地「:[目的地:」平面文件目的地「],[文件名:」C:\ bkpDB.txt「],[檢查」第一行數據行中的列名稱「]並且不要更改其他內容,從一個或多個表中的數據複製‘選擇‘下一步’

  4. 頁‘配置平面文件目標’:下一步」

  5. 頁‘指定表複製或查詢’選擇’:選擇表,行和列分隔符選擇「下一步」,最後是「芬蘭」

如果要加載從.txt文件數據庫,你應該如下:

  1. 使用特定路徑(如C:\ bkpDB)中的文本文件。(數據庫名稱) - >選擇(「任務」) - >選擇(「導入數據」) - >爲「歡迎頁面」選擇「下一步」 - >並轉到下一頁 - >

  2. 頁面「選擇數據源」:[數據源:「平面文件源」],[文件名:「C:\ bkpDB.txt」],[選中「列的第一個數據行中的名稱」]不要別的任何改變,選擇‘下一步’

  3. 頁‘選擇一個目標’中進行選擇:選擇你的數據庫,然後選擇‘下一步’,‘芬蘭’

如果您要使用密碼加密和解密,所以我建議你使用高級加密標準AES算法

using System; 
 
using System.Collections.Generic; 
 
using System.IO; 
 
using System.Linq; 
 
using System.Security.Cryptography; 
 
using System.Text; 
 
using System.Web; 
 
using System.Web.Mvc; 
 

 
namespace MvcWebRole1.Controllers 
 
{ 
 
    public class AESController : Controller 
 
    { 
 
     // 
 
     // GET: /AES/ 
 

 
     public ActionResult Index() 
 
     { 
 
      ViewData["Encrypted"] = TempData["TEncrypted"]; 
 
      ViewData["Decrypted"] = TempData["TDecrypted"]; 
 
      return View(); 
 
      
 
     } 
 

 
     //Text is PlainText 
 
     //Key is Public Secret Key 
 
     [HttpPost] 
 
     public ActionResult Encryption(string Text, string Key) 
 
     { 
 
      // Convert String to Byte 
 

 
      byte[] MsgBytes = Encoding.UTF8.GetBytes(Text); 
 
      byte[] KeyBytes = Encoding.UTF8.GetBytes(Key); 
 

 
      // Hash the password with SHA256 
 
      //Secure Hash Algorithm 
 
      //Operation And, Xor, Rot,Add (mod 232),Or, Shr 
 
      //block size 1024 
 
      //Rounds 80 
 
      //rotation operator , rotates point1 to point2 by theta1=> p2=rot(t1)p1 
 
      //SHR shift to right 
 
      KeyBytes = SHA256.Create().ComputeHash(KeyBytes); 
 

 
      byte[] bytesEncrypted = AES_Encryption(MsgBytes, KeyBytes); 
 

 
      string encryptionText = Convert.ToBase64String(bytesEncrypted); 
 

 

 

 
      TempData["TEncrypted"] = encryptionText; 
 
      return RedirectToAction("Index"); 
 
     } 
 

 
     public byte[] AES_Encryption(byte[] Msg, byte[] Key) 
 
     { 
 
      byte[] encryptedBytes = null; 
 

 
      //salt is generated randomly as an additional number to hash password or message in order o dictionary attack 
 
      //against pre computed rainbow table 
 
      //dictionary attack is a systematic way to test all of possibilities words in dictionary wheather or not is true? 
 
      //to find decryption key 
 
      //rainbow table is precomputed key for cracking password 
 
      // Set your salt here, change it to meet your flavor: 
 
      // The salt bytes must be at least 8 bytes. == 16 bits 
 
      byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; 
 

 
      using (MemoryStream ms = new MemoryStream()) 
 
      { 
 
       using (RijndaelManaged AES = new RijndaelManaged()) 
 
       { 
 
        AES.KeySize = 256; 
 
        AES.BlockSize = 128; 
 

 
        var key = new Rfc2898DeriveBytes(Key, saltBytes, 1000); 
 
        AES.Key = key.GetBytes(AES.KeySize/8); 
 
        AES.IV = key.GetBytes(AES.BlockSize/8); 
 

 
        AES.Mode = CipherMode.CBC; 
 

 
        using (var cs = new CryptoStream(ms, AES.CreateEncryptor(), CryptoStreamMode.Write)) 
 
        { 
 
         cs.Write(Msg, 0, Msg.Length); 
 
         cs.Close(); 
 
        } 
 
        encryptedBytes = ms.ToArray(); 
 
       } 
 
      } 
 

 
      return encryptedBytes; 
 
     } 
 

 
     [HttpPost] 
 
     public ActionResult Decryption(string Text2, string Key2) 
 
     { 
 
      // Convert String to Byte 
 
      byte[] MsgBytes = Convert.FromBase64String(Text2); 
 
      byte[] KeyBytes = Encoding.UTF8.GetBytes(Key2); 
 
      KeyBytes = SHA256.Create().ComputeHash(KeyBytes); 
 

 
      byte[] bytesDecrypted = AES_Decryption(MsgBytes, KeyBytes); 
 

 
      string decryptionText = Encoding.UTF8.GetString(bytesDecrypted); 
 

 

 
      TempData["TDecrypted"] = decryptionText; 
 
      return RedirectToAction("Index"); 
 
     } 
 

 
     public byte[] AES_Decryption(byte[] Msg, byte[] Key) 
 
     { 
 
      byte[] decryptedBytes = null; 
 

 
      // Set your salt here, change it to meet your flavor: 
 
      // The salt bytes must be at least 8 bytes. 
 
      byte[] saltBytes = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8 }; 
 

 
      using (MemoryStream ms = new MemoryStream()) 
 
      { 
 
       using (RijndaelManaged AES = new RijndaelManaged()) 
 
       { 
 
        AES.KeySize = 256; 
 
        AES.BlockSize = 128; 
 

 
        var key = new Rfc2898DeriveBytes(Key, saltBytes, 1000); 
 
        AES.Key = key.GetBytes(AES.KeySize/8); 
 
        AES.IV = key.GetBytes(AES.BlockSize/8); 
 

 
        AES.Mode = CipherMode.CBC; 
 

 
        using (var cs = new CryptoStream(ms, AES.CreateDecryptor(), CryptoStreamMode.Write)) 
 
        { 
 
         cs.Write(Msg, 0, Msg.Length); 
 
         cs.Close(); 
 
        } 
 
        decryptedBytes = ms.ToArray(); 
 
       } 
 
      } 
 

 
      return decryptedBytes; 
 
     } 
 
    } 
 
}

在視圖部分(「指數」) :

@{ 
 
    ViewBag.Title = "Index"; 
 
    Layout = "~/Views/Shared/_Layout.cshtml"; 
 
} 
 

 

 
<h2>Encryption And Decryption</h2> 
 

 
<div style="color:red;" id="EncryptedText">Encrypted Message: @ViewData["Encrypted"]</div> 
 

 
<br /> 
 
<div style="color:red;" id="DecryptedText">Decrypted Message: @ViewData["Decrypted"]</div> 
 
<br /> 
 

 

 
    @using(Html.BeginForm("Encryption", "AES", FormMethod.Post)) 
 
    { 
 
     <label id="lbk1">Key:</label><input name="Key" id="Key" type="text" /> 
 
     <br /> 
 
     <label id="lbk2">Message:</label><input name="Text" id="Text" type="text" /> 
 
     <br /> 
 
     <input id="btnEncryption" type="submit" value="Encryption" /> 
 
     <br /> 
 
     <br />   
 
    } 
 

 
@using(Html.BeginForm("Decryption", "AES", FormMethod.Post)) 
 
    { 
 
     <label id="lbk4">Enter Same Key:</label><input name="Key2" id="Key2" type="text" /> 
 
     <br /> 
 
     <label id="lbk5">Enter Encrypted Message:</label><input name="Text2" id="Text2" type="text" /> 
 
     <br /> 
 
\t  <input id="btnDecryption" type="submit" value="Decryption" /> 
 
\t 
 
    } 
 

 

 
<br />

編輯:

要創建內部應用程序數據庫,你可以使用來自另一個數據庫的存儲過程和調用此SP當用戶想要創建(從用戶應用程序創建的數據庫(「密度纖維板」))數據庫(.MDF)並傳遞值,諸如數據庫名稱等

CREATE PROC dbo.dbbase 
 
AS 
 

 
DECLARE @db varchar(50), @sql varchar(1000) 
 
    
 
    IF DB_ID(@db) IS NULL 
 
    SELECT @SQL = 'CREATE DATABASE ' + @db + 
 
       ' ON (NAME = ' + @db + '_Data, FILENAME = ''C:\UserName\' + @db + '.mdf'')' + 
 
       ' LOG ON (NAME = ' + @db + '_Log, FILENAME = ''C:\UserName\' + @db + '.mdf'')' 
 

 
    EXEC(@sql) 
 

 
GO

我希望它適合你。

+0

感謝這個開始,但是這不正是我期待的:( 我。不想來存儲我的txt文件數據庫檢查更新的第一篇文章:) – titol

+0

親愛@titol請讓我知道如果我正確地知道了:你必須爲用戶的應用程序,他們可以選擇數據庫類型,如:(。 txt)或(.mdf),然後上傳數據庫文件到所需的路徑。您想知道如何將「.mdf」存儲到所需的路徑中?儘管我已經提出了在上面的代碼中散列字符串的好方法。 –

+0

請看看我的答案(編輯部分) –